SPARQL语法入门 #

一、SPARQL概述 #

1.1 什么是SPARQL #

SPARQL(SPARQL Protocol and RDF Query Language)是W3C推荐的RDF数据查询语言标准。

text
SPARQL特点:
├── W3C标准
├── 声明式查询语言
├── 模式匹配查询
├── 支持推理
├── 支持联邦查询
└── 多种查询形式

1.2 查询形式 #

text
查询形式:
├── SELECT:返回变量绑定结果
├── ASK:返回布尔值
├── CONSTRUCT:构建新的RDF图
└── DESCRIBE:描述资源

二、命名空间 #

2.1 常用命名空间 #

sparql
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

2.2 自定义命名空间 #

sparql
PREFIX ex: <http://example.org/>
PREFIX person: <http://example.org/person/>
PREFIX product: <http://example.org/product/>

SELECT ?name
WHERE {
  person:1 foaf:name ?name .
}

三、基本图模式 #

3.1 三元组模式 #

sparql
# 简单三元组
SELECT ?s ?p ?o
WHERE {
  ?s ?p ?o .
}

# 指定主语
SELECT ?p ?o
WHERE {
  ex:Tom ?p ?o .
}

# 指定谓语
SELECT ?s ?o
WHERE {
  ?s foaf:name ?o .
}

# 完整指定
SELECT ?name
WHERE {
  ex:Tom foaf:name ?name .
}

3.2 多三元组模式 #

sparql
# 多条件AND
SELECT ?name ?email
WHERE {
  ?person foaf:name ?name .
  ?person foaf:mbox ?email .
}

# 使用分号简写
SELECT ?name ?email
WHERE {
  ?person foaf:name ?name ;
          foaf:mbox ?email .
}

# 使用逗号简写
SELECT ?name
WHERE {
  ?person foaf:name ?name , ?alternateName .
}

3.3 变量绑定 #

sparql
# 变量命名
SELECT ?person ?name ?age
WHERE {
  ?person a ex:Person .
  ?person foaf:name ?name .
  ?person ex:age ?age .
}

# 变量重用
SELECT ?friend
WHERE {
  ex:Tom ex:knows ?friend .
  ex:Jerry ex:knows ?friend .
}

四、过滤表达式 #

4.1 比较运算符 #

sparql
# 等于
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  FILTER (?age = 30)
}

# 不等于
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  FILTER (?age != 30)
}

# 大于、小于
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  FILTER (?age > 25 && ?age < 40)
}

4.2 逻辑运算符 #

sparql
# AND
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  ?person ex:status ?status .
  FILTER (?age > 25 && ?status = "active")
}

# OR
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:status ?status .
  FILTER (?status = "active" || ?status = "pending")
}

# NOT
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:status ?status .
  FILTER (!(?status = "inactive"))
}

4.3 字符串函数 #

sparql
# 字符串匹配
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (STRSTARTS(?name, "T"))
}

# 包含
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (CONTAINS(?name, "om"))
}

# 正则表达式
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (REGEX(?name, "^T.*m$", "i"))
}

# 字符串长度
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (STRLEN(?name) > 3)
}

# 大小写转换
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (LCASE(?name) = "tom")
}

4.4 数值函数 #

sparql
# 数学运算
SELECT ?name ?priceWithTax
WHERE {
  ?product foaf:name ?name .
  ?product ex:price ?price .
  BIND (?price * 1.1 AS ?priceWithTax)
}

# 范围过滤
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  FILTER (?age >= 20 && ?age <= 40)
}

4.5 类型检查 #

sparql
# 检查是否为数字
SELECT ?value
WHERE {
  ?s ?p ?value .
  FILTER (isNumeric(?value))
}

# 检查是否为字符串
SELECT ?value
WHERE {
  ?s ?p ?value .
  FILTER (isLiteral(?value) && DATATYPE(?value) = xsd:string)
}

# 检查是否为URI
SELECT ?value
WHERE {
  ?s ?p ?value .
  FILTER (isIRI(?value))
}

五、可选模式 #

5.1 OPTIONAL #

sparql
# 可选属性
SELECT ?name ?email
WHERE {
  ?person foaf:name ?name .
  OPTIONAL { ?person foaf:mbox ?email }
}

# 多个可选
SELECT ?name ?email ?phone
WHERE {
  ?person foaf:name ?name .
  OPTIONAL { ?person foaf:mbox ?email }
  OPTIONAL { ?person ex:phone ?phone }
}

# 可选条件
SELECT ?name ?friendName
WHERE {
  ?person foaf:name ?name .
  OPTIONAL {
    ?person ex:knows ?friend .
    ?friend foaf:name ?friendName .
  }
}

5.2 FILTER NOT EXISTS #

sparql
# 不存在某属性
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER NOT EXISTS { ?person foaf:mbox ?email }
}

# 不存在某关系
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER NOT EXISTS {
    ?person ex:knows ex:Jerry .
  }
}

5.3 EXISTS #

sparql
# 存在某属性
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER EXISTS { ?person foaf:mbox ?email }
}

# 存在某关系
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER EXISTS {
    ?person ex:knows ex:Jerry .
  }
}

六、联合模式 #

6.1 UNION #

sparql
# 简单联合
SELECT ?name
WHERE {
  {
    ?person foaf:firstName ?name .
  }
  UNION
  {
    ?person foaf:lastName ?name .
  }
}

# 多个联合
SELECT ?name
WHERE {
  {
    ?person foaf:name ?name .
  }
  UNION
  {
    ?person foaf:nick ?name .
  }
  UNION
  {
    ?person foaf:firstName ?name .
  }
}

# 带条件的联合
SELECT ?name ?type
WHERE {
  {
    ?person foaf:name ?name .
    BIND ("full" AS ?type)
  }
  UNION
  {
    ?person foaf:nick ?name .
    BIND ("nick" AS ?type)
  }
}

七、属性路径 #

7.1 路径表达式 #

sparql
# 序列路径
SELECT ?friend
WHERE {
  ex:Tom foaf:knows/foaf:knows ?friend .
}

# 零次或多次
SELECT ?ancestor
WHERE {
  ex:Tom ex:parent* ?ancestor .
}

# 一次或多次
SELECT ?descendant
WHERE {
  ex:Tom ex:parent+ ?descendant .
}

# 零次或一次
SELECT ?parent
WHERE {
  ex:Tom ex:parent? ?parent .
}

7.2 路径操作符 #

sparql
# 路径选择(OR)
SELECT ?related
WHERE {
  ex:Tom (foaf:knows | foaf:follows) ?related .
}

# 反向路径
SELECT ?follower
WHERE {
  ?follower ^foaf:knows ex:Tom .
}

# 路径组合
SELECT ?friend
WHERE {
  ex:Tom (foaf:knows/ex:worksAt/^ex:worksAt) ?friend .
}

7.3 路径长度 #

sparql
# 获取路径长度
SELECT ?friend (COUNT(?step) AS ?distance)
WHERE {
  ex:Tom (foaf:knows{1,3}) ?friend .
}
GROUP BY ?friend

八、排序与分页 #

8.1 ORDER BY #

sparql
# 升序排序
SELECT ?name ?age
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
}
ORDER BY ?name

# 降序排序
SELECT ?name ?age
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
}
ORDER BY DESC(?age)

# 多字段排序
SELECT ?name ?age
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
}
ORDER BY DESC(?age) ?name

8.2 LIMIT和OFFSET #

sparql
# 限制结果数量
SELECT ?name
WHERE {
  ?person foaf:name ?name .
}
LIMIT 10

# 分页
SELECT ?name
WHERE {
  ?person foaf:name ?name .
}
ORDER BY ?name
LIMIT 10
OFFSET 20

九、聚合函数 #

9.1 COUNT #

sparql
# 计数
SELECT (COUNT(?person) AS ?count)
WHERE {
  ?person a ex:Person .
}

# 分组计数
SELECT ?status (COUNT(?person) AS ?count)
WHERE {
  ?person a ex:Person .
  ?person ex:status ?status .
}
GROUP BY ?status

9.2 SUM/AVG/MAX/MIN #

sparql
# 求和
SELECT (SUM(?age) AS ?totalAge)
WHERE {
  ?person ex:age ?age .
}

# 平均值
SELECT (AVG(?age) AS ?avgAge)
WHERE {
  ?person ex:age ?age .
}

# 最大值
SELECT (MAX(?age) AS ?maxAge)
WHERE {
  ?person ex:age ?age .
}

# 最小值
SELECT (MIN(?age) AS ?minAge)
WHERE {
  ?person ex:age ?age .
}

9.3 GROUP BY和HAVING #

sparql
# 分组聚合
SELECT ?department (AVG(?age) AS ?avgAge) (COUNT(?person) AS ?count)
WHERE {
  ?person ex:department ?department .
  ?person ex:age ?age .
}
GROUP BY ?department

# HAVING过滤
SELECT ?department (AVG(?age) AS ?avgAge)
WHERE {
  ?person ex:department ?department .
  ?person ex:age ?age .
}
GROUP BY ?department
HAVING (AVG(?age) > 30)

十、BIND和VALUES #

10.1 BIND #

sparql
# 计算绑定
SELECT ?name ?fullName
WHERE {
  ?person foaf:firstName ?firstName .
  ?person foaf:lastName ?lastName .
  BIND (CONCAT(?firstName, " ", ?lastName) AS ?fullName)
}

# 条件绑定
SELECT ?name ?ageGroup
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  BIND (
    IF(?age < 30, "young",
      IF(?age < 50, "middle", "senior")
    ) AS ?ageGroup
  )
}

10.2 VALUES #

sparql
# 内联数据
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  VALUES ?person { ex:Tom ex:Jerry ex:Mike }
}

# 多变量
SELECT ?person ?name
WHERE {
  ?person foaf:name ?name .
  VALUES (?person ?status) {
    (ex:Tom "active")
    (ex:Jerry "inactive")
  }
}

十一、子查询 #

sparql
# 子查询
SELECT ?name ?avgAge
WHERE {
  ?person foaf:name ?name .
  ?person ex:department ?dept .
  {
    SELECT ?dept (AVG(?age) AS ?avgAge)
    WHERE {
      ?person ex:department ?dept .
      ?person ex:age ?age .
    }
    GROUP BY ?dept
  }
  FILTER (?dept = ?dept)
}

十二、总结 #

SPARQL语法要点:

类别 语法 说明
命名空间 PREFIX 定义前缀
图模式 WHERE 定义查询模式
过滤 FILTER 条件过滤
可选 OPTIONAL 可选模式
联合 UNION 联合查询
聚合 GROUP BY 分组聚合

下一步,让我们学习查询模式!

最后更新:2026-03-27