SPARQL:查找所有子对象都符合条件的对象
SPARQL: find objects with all sub-objects matching a criteria
鉴于此数据,每个人都可以选择有一个 "smart" 谓词,并且每个部门可能有零个或多个人,我需要找到只包含聪明人的部门。结果应该只包括部门 1 和 2。理想情况下,结果还应该包括每个部门的 "smart" 个对象。谢谢!
person:A p:type 'p' ;
p:smart 'yes' .
person:B p:type 'p' ;
p:smart 'maybe' .
person:C p:type 'p' .
department:1 p:type 'd' ;
p:has person:A, person:B .
department:2 p:type 'd' ;
p:has person:B .
department:3 p:type 'd' ;
p:has person:B, person:C .
department:4 p:type 'd' .
双重否定之类的东西可能会起作用:
SELECT DISTINCT ?dept WHERE {
?dept p:has ?person .
FILTER NOT EXISTS {
?dept p:has ?person1 .
FILTER NOT EXISTS {
?person1 p:smart ?smartVal
}
}
}
结果:
+---------------+
| dept |
+---------------+
| department:1 |
| department:2 |
+---------------+
具有值:
SELECT ?dept (GROUP_CONCAT(DISTINCT ?smart;separator=";") as ?smartValues) WHERE {
?dept p:has ?person .
?person p:smart ?smart
FILTER NOT EXISTS {
?dept p:has ?person1 .
FILTER NOT EXISTS {
?person1 p:smart ?smartVal
}
}
}
GROUP BY ?dept
结果:
+---------------+-------------+
| dept | smartValues |
+---------------+-------------+
| department:1 | maybe;yes |
| department:2 | maybe |
+---------------+-------------+
我觉得我以前回答过类似的问题,但无论如何有一个相当不错的方法来做到这一点:
select ?dept
(count(?person) as ?pc) (count(?smart) as ?sc)
(group_concat(?smart; separator=',') as ?smarts)
{
?dept p:has ?person .
optional { ?person p:smart ?smart }
}
group by ?dept
having (?pc = ?sc)
即:查找部门、人员和(如果可用)智能值。为每个部门找到人数与智能值数量匹配的部门。
-------------------------------------------------------------
| dept | pc | sc | smarts |
=============================================================
| <http://example.com/department#2> | 1 | 1 | "maybe" |
| <http://example.com/department#1> | 2 | 2 | "yes,maybe" |
-------------------------------------------------------------
当您想获得每个对象的结果时,匹配某些条件,group by
/ having
通常是最干净的答案(因为您可以将匹配与过滤分开)。
鉴于此数据,每个人都可以选择有一个 "smart" 谓词,并且每个部门可能有零个或多个人,我需要找到只包含聪明人的部门。结果应该只包括部门 1 和 2。理想情况下,结果还应该包括每个部门的 "smart" 个对象。谢谢!
person:A p:type 'p' ;
p:smart 'yes' .
person:B p:type 'p' ;
p:smart 'maybe' .
person:C p:type 'p' .
department:1 p:type 'd' ;
p:has person:A, person:B .
department:2 p:type 'd' ;
p:has person:B .
department:3 p:type 'd' ;
p:has person:B, person:C .
department:4 p:type 'd' .
双重否定之类的东西可能会起作用:
SELECT DISTINCT ?dept WHERE {
?dept p:has ?person .
FILTER NOT EXISTS {
?dept p:has ?person1 .
FILTER NOT EXISTS {
?person1 p:smart ?smartVal
}
}
}
结果:
+---------------+
| dept |
+---------------+
| department:1 |
| department:2 |
+---------------+
具有值:
SELECT ?dept (GROUP_CONCAT(DISTINCT ?smart;separator=";") as ?smartValues) WHERE {
?dept p:has ?person .
?person p:smart ?smart
FILTER NOT EXISTS {
?dept p:has ?person1 .
FILTER NOT EXISTS {
?person1 p:smart ?smartVal
}
}
}
GROUP BY ?dept
结果:
+---------------+-------------+
| dept | smartValues |
+---------------+-------------+
| department:1 | maybe;yes |
| department:2 | maybe |
+---------------+-------------+
我觉得我以前回答过类似的问题,但无论如何有一个相当不错的方法来做到这一点:
select ?dept
(count(?person) as ?pc) (count(?smart) as ?sc)
(group_concat(?smart; separator=',') as ?smarts)
{
?dept p:has ?person .
optional { ?person p:smart ?smart }
}
group by ?dept
having (?pc = ?sc)
即:查找部门、人员和(如果可用)智能值。为每个部门找到人数与智能值数量匹配的部门。
-------------------------------------------------------------
| dept | pc | sc | smarts |
=============================================================
| <http://example.com/department#2> | 1 | 1 | "maybe" |
| <http://example.com/department#1> | 2 | 2 | "yes,maybe" |
-------------------------------------------------------------
当您想获得每个对象的结果时,匹配某些条件,group by
/ having
通常是最干净的答案(因为您可以将匹配与过滤分开)。