我有这个问题:
prefix : <http://test.example/>
select ?anotherUser (COUNT(?anotherItem) as ?countOfSharedLikedItems)
WHERE
{
values ?user {:ania}.
?anotherUser :likes ?anotherItem.
filter (?anotherUser != ?user)
filter exists {?user :likes ?anotherItem}
}
group by ?anotherUser
order by desc(?countOfSharedLikedItems)
该数据运行:
@prefix : <http://test.example/> .
:alice :likes :beethoven.
:alice :likes :verdi.
:sofia :likes :beethoven.
:sofia :likes :verdi.
:sofia :likes :rossini.
:sofia :likes :mozart.
:ania :likes :verdi.
:ania :likes :beethoven.
:ania :likes :david.
:david :likes :ania.
:david :likes :beethoven.
:david :likes :verdi.
:antonino :likes :verdi.
:antonino :likes :mozart.
:weirdo :likes :katyperry.
:beethoven a :recommendable.
:verdi a :recommendable.
:rossini a :recommendable.
:katyperry a :recommendable.
:mozart a :recommendable.
它工作正常,我正在进行聚合并将值绑定到名为countOfSharedLikedItems
的变量。现在我想获得该参数的最大值,我试过这个:
prefix : <http://test.example/>
select
?anotherUser
(MAX(?countOfSharedLikedItems) as ?max)
(COUNT(?anotherItem) as ?countOfSharedLikedItems)
WHERE
{
values ?user { :ania }.
?anotherUser :likes ?anotherItem.
filter (?anotherUser != ?user)
filter exists { ?user :likes ?anotherItem }
}
group by ?anotherUser
order by desc(?countOfSharedLikedItems)
但变量max
的结果始终为空。
我做错了什么?
提示我确实需要输出中的三个变量anotherUser
,countOfSharedLikedItems
和max
。否则,我会做一个外部选择,我可以获得最大值,但我需要其中的三个,这就是我要问的原因,因为我自己无法做到这一点
我尝试了这个 SILLY 解决方案,它有效,但显然很傻
prefix : <http://test.example/>
select ?anotherUser ?countOfSharedLikedItems ?maxSharedLikedItems
WHERE {
{
select
?anotherUser
(COUNT(?anotherItem) as ?countOfSharedLikedItems)
WHERE
{
values ?user { :ania }.
?anotherUser :likes ?anotherItem.
filter (?anotherUser != ?user)
filter exists { ?user :likes ?anotherItem }
}
group by ?anotherUser
order by desc(?countOfSharedLikedItems)
}
{
select (MAX(?countOfSharedLikedItems) as ?maxSharedLikedItems)
WHERE
{
select
?anotherUser
(COUNT(?anotherItem) as ?countOfSharedLikedItems)
WHERE
{
values ?user { :ania }.
?anotherUser :likes ?anotherItem.
filter (?anotherUser != ?user)
filter exists { ?user :likes ?anotherItem }
}
group by ?anotherUser
}
}
}
你能检查一下并提出另一个更好的解决方案吗?
答案 0 :(得分:1)
最外层查询的结构在这些部分中存在致命问题:
select
(MAX(?countOfSharedLikedItems) as ?max)
(COUNT(?anotherItem) as ?countOfSharedLikedItems)
WHERE { ... }
group by ?anotherUser
您需要完全了解分组的内容。 其中部分中的三元组提供了一堆结果行。例如,在像
这样的查询中select * where {
?s ?p ?o
}
结果是一堆行,每行都有一个每个变量的值。当您添加 group by 子句时,您说要将这些行分区为一堆集。例如,如果结果是
s1 p1 o1
s1 p2 o2
s2 p1 o2
s2 p1 o3
s3 p1 o2
你用?s分组,然后你将这些结果分成如下:
s1
[ p1 o1 ]
[ p2 o2 ]
s2
[ p1 o2 ]
[ p1 o3 ]
s3
[ p1 o2 ]
对于每个唯一的s值,您仍然有一堆行,每行都提供p和o值。聚合函数在这些串上运行。所以当你做类似的事情时
select ?s (max(?o) as ?oMax) where {
?s ?p ?o
}
group by ?s
max 聚合可以在每个束上工作,即在[o1,o2],[o2,o3]和[o2]上,并从每个束产生一个值。像
这样的东西select
(count(?o) as ?numO)
(max(?numO) as ?oMax)
group by ?s
没有意义。当你按分组进行分组时,计数在每一组中运行,并且有一些值,所以你可以计算它们。但是 max 也会尝试在每一组内进行操作,但是这些束没有任何绑定?numO来查看。即使你可以使用 count(?o)中的值,每个只有一个,所以 max 会只是回归那个价值。