

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在查询的 FILTER、FILTER...IN 和 VALUES 之间进行选择
<a name="best-practices-sparql-batch"></a>

有三种方法在 SPARQL 查询中注入值：`FILTER`、`FILTER...IN` 和 `VALUES`。

例如，假设您要在单个查询内查找多个人员的好友。您可以使用 `FILTER` 构建查询，如下所示：

```
  PREFIX ex: <https://www.example.com/>
  PREFIX foaf : <http://xmlns.com/foaf/0.1/>

  SELECT ?s ?o
  WHERE {?s foaf:knows ?o. FILTER (?s = ex:person1 || ?s = ex:person2)}
```

这将返回图形中 `?s` 绑定到 `ex:person1` 或 `ex:person2` 并且传出边缘标记为 `foaf:knows` 的所有三元组。

您也可以创建一个使用 `FILTER...IN` 的查询，该查询返回等同的结果：

```
  PREFIX ex: <https://www.example.com/>
  PREFIX foaf : <http://xmlns.com/foaf/0.1/>

  SELECT ?s ?o
  WHERE {?s foaf:knows ?o. FILTER (?s IN (ex:person1, ex:person2))}
```

您也可以使用 `VALUES` 创建查询，在此例中也会返回等同结果：

```
  PREFIX ex: <https://www.example.com/>
  PREFIX foaf : <http://xmlns.com/foaf/0.1/>

  SELECT ?s ?o
  WHERE {?s foaf:knows ?o. VALUES ?s {ex:person1 ex:person2}}
```

尽管在许多情况下，这些查询在语义上是等效的，但在某些情况下，两个 `FILTER` 变体不同于 `VALUES` 变体：
+ 第一种情况是在您注入重复值时，例如将同一个人注入两次。在这种情况下，`VALUES` 查询会在结果中包含重复项。您可通过将 `DISTINCT` 添加到 `SELECT` 子句来显式消除此类重复。但是，在某些情况下，您可能希望在查询结果中包含重复项用于冗余值注入。

  而 `FILTER` 和 `FILTER...IN` 在相同值多次显示时仅提取该值一次。
+ 第二种情况涉及 `VALUES` 始终执行完全匹配，而 `FILTER` 在某些情况下可能会应用类型提升并执行模糊匹配。

  例如，当您在 values 子句中包含类似于 `"2.0"^^xsd:float` 的文本时，`VALUES` 查询与此文本完全匹配，包括文本值和数据类型。

  相比之下，`FILTER` 会为这些数字文本生成模糊匹配。该匹配会包括值相同但数字数据类型（例如 `xsd:double`）不同的文本。
**注意**  
枚举字符串文本或 URI 时，`FILTER` 与 `VALUES` 的行为没有区别。

`FILTER` 与 `VALUES` 之间的区别会影响优化以及所造成的查询计算策略。除非您的用例需要模糊匹配，否则我们建议您使用 `VALUES`，因为它会避免查找与类型转换相关的特殊情况。因此，`VALUES` 通常会生成更高效的查询，运行速度更快，而且成本更低。