为了获得子查询结果的笛卡尔积,我复制了查询并将结果绑定到不同的变量。但是内部查询很长,除SELECT
行之外完全相同。有没有办法简化这个?
我在下面添加了我的查询的简化版本。我实际上要做的是在一系列事件中找到时间表冲突。事件由子查询选择。
SELECT ?a1 ?b1 ?a2 ?b2
WHERE {
SELECT (?a AS ?a1) (?b AS ?b1)
WHERE {
# long query with ?a and ?b
}
SELECT (?a AS ?a2) (?b AS ?b2)
WHERE {
# long query with ?a and ?b
}
FILTER (?a1 < ?a2)
}
答案 0 :(得分:1)
您正在进行查询,并获得结果(两次):
{ < x1, y1>, < x2, y2 >, < x3, y3 >, ... }
{ < x1, y1>, < x2, y2 >, < x3, y3 >, ... }
然后,您想要过滤那些结果对,其中第一组中的第一个值小于第二个中的第一个。
现在结果数量将快速增加,O(N ^ 2)。无论如何,你真的不需要为此烦恼。假设(不失一般性)您按第一个值(升序)对结果进行排序。然后你的第一批结果(由*
表示)是:
{ *< x1, y1>*, < x2, y2 >, < x3, y3 >, ... }
{ < x1, y1>, *< x2, y2 >*, *< x3, y3 >*, ... and everything else ... }
第二个:
{ < x1, y1>, *< x2, y2 >*, < x3, y3 >, ... }
{ < x1, y1>, < x2, y2 >, *< x3, y3 >*, ... and everything else ... }
等等
所以你在空间方面做得更好,而且可能是时间问题,只需发出查询:
SELECT ?a ?b
WHERE {
# long query with ?a and ?b
}
ORDER BY ?a # defaults to ASCending
将其放入数组或类似数据中,并循环获取项目results[i], results[j] where i > j
。
答案 1 :(得分:1)
user205512's answer是正确的小巷。我不认为这是获取任意查询的笛卡尔积的简单方法。让服务器执行此操作是有利的,也就是说可以流式传输结果,避免大量的中间存储,如果您只是接受结果并自行计算笛卡尔积,则可能需要这样做。
但是,我要指出的是,根据您的特定查询,以可能为您计算笛卡尔积的方式重写它可能不会太困难。这取决于特定的查询,但想法是您可以使用对象列表表示法并使用属性路径将变量移动到对象位置。例如,考虑一个类似的查询:
?a :p/:q ?b
您可以利用这与
形式的数据匹配的事实X→ p Y→ q Z
将查询重写为:
[] ^:p ?a ; :q ?b
现在,您可以使用逗号分隔的对象列表匹配两组?a和?b:
[] ^:p ?a1, ?a2 ; :q ?b1, ?b2
当然,你不能将它用于每个查询,你可能仍然需要复制某些部分,例如过滤表达式,但它可能是一个可行的选择。