SPARQL 中嵌套 IF 语句的语法
Syntax for nested IF statements in SPARQL
我正在尝试 运行 以下 SPARQL 查询,但它一直在 returning SR171: Transaction timed out
。
SELECT ?isBusAvailable WHERE {
SELECT DISTINCT IF (
(
SELECT ?value2 WHERE {
GRAPH data: { ?obsValueID2 ontology:value ?value2 }
GRAPH data: { ?obsValueID2 rdf:label "Availability" }
GRAPH data: { ?obsValueID2 ontology:isObservedValueOf ?obsID2}
GRAPH data: { ?obsID2 ssn:observationResultTime ?time2 }
GRAPH data: { ?obsID2 ssn:observedBy ?id2 }
GRAPH meta: { ?id2 rdf:label "MyBusService" }
} ORDER BY DESC (?time2) LIMIT 1) > 1, "Take Bus", (
SELECT ?isBikeAvailable WHERE {
SELECT DISTINCT IF (
(
SELECT ?value3 WHERE {
GRAPH data: { ?obsValueID3 ontology:value ?value3 }
GRAPH data: { ?obsValueID3 rdf:label "Availability" }
GRAPH data: { ?obsValueID3 ontology:isObservedValueOf ?obsID3}
GRAPH data: { ?obsID3 ssn:observationResultTime ?time3 }
GRAPH data: { ?obsID3 ssn:observedBy ?id3 }
GRAPH meta: { ?id3 rdf:label "MyBikeService" }
} ORDER BY DESC (?time3) LIMIT 1
) > 0, "Take Bike", "Take Taxi") as ?isBikeAvailable WHERE { ?1 ?2 ?3}})) as ?isBusAvailable WHERE { ?4 ?5 ?6}}
如果我单独 运行 它们,它 运行 不到 1 秒。以下示例有效。
SELECT ?isBusAvailable WHERE {
SELECT DISTINCT IF (
(
SELECT ?value2 WHERE {
GRAPH data: { ?obsValueID2 ontology:value ?value2 }
GRAPH data: { ?obsValueID2 rdf:label "Availability" }
GRAPH data: { ?obsValueID2 ontology:isObservedValueOf ?obsID2}
GRAPH data: { ?obsID2 ssn:observationResultTime ?time2 }
GRAPH data: { ?obsID2 ssn:observedBy ?id2 }
GRAPH meta: { ?id2 rdf:label "MyBusService" }
} ORDER BY DESC (?time2) LIMIT 1) > 1, "Take Bus", 'Take Bike') as ?isBusAvailable WHERE { ?4 ?5 ?6}}
如果第一个查询的结果为真,return 'Take Bus';否则,运行 第二个查询,return 'Take Bike' 或 'Take Taxi'。
显然问题出在第二个查询上(来自第一个查询的错误条件)。在 "Take Bus" 之后,如果我将第二个查询更改为 "Take Bike",它会起作用。
假条件下的查询需要遵循 SPARQL 中 IF 条件语句的格式,因为它 returns 是一个值。删除 "SELECT DISTINCT"
SELECT ?isBusAvailable WHERE {
SELECT DISTINCT (IF(
(
SELECT ?value WHERE {
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID}
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBusService" }
} ORDER BY DESC (?time) LIMIT 1) > 0,'Take Bus', (
IF (
(
SELECT ?value WHERE {
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID}
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBikeService" }
} ORDER BY DESC (?time) LIMIT 1
) > 0, "Take Bike", "Take Taxi")
)) AS ?isBusAvailable) FROM data: WHERE { ?1 ?2 ?3 }}
编辑: select distinct if( ... )
不是合法的 SPARQL,因此 if 语句需要包含在括号中。查询变为:select distinct (if( ... ))
@andrei -- 我认为你的 ?isBusAvailable
混淆了事情 -- 考虑到你最后 return 的字面值,这可能更好 ?travelMethod
。
当我读到东西时,这里的问题实际上是如何正确构造嵌套的 IFs
——问题的标题也许应该是 "What is correct syntax for nesting IF statements in SPARQL?"
在简单流程中,我认为您正在做的是检查可用总线,如果存在,returning "Take bus";如果没有,则检查是否有可用的自行车,如果存在,则 return "Take bike";如果没有,你 return "Take taxi"。在 psuedo-code、IF AVAIL bus, THEN take bus, ELSE ( IF AVAIL bike, THEN take bike, ELSE take taxi )
.
@joshua-taylor 在一件事上是正确的 — SELECT DISTINCT IF (…)
严格来说不是有效的,但修复只是一个额外的 paren 包装器 — 例如,以下是有效的(并验证)— -
SELECT DISTINCT ( IF ( ( 1 = 1 )
, "true"
, "false"
) AS ?test )
WHERE { ?x ?y ?z }
LIMIT 1
但是在您的查询中修复此问题并没有从验证器获得更好的输出。事实上,用 1
替换内部 (SELECT ?value … LIMIT 1)
查询会使整个大型查询有效 -
SELECT ?travelMethod
WHERE
{
SELECT DISTINCT
( IF
(
(
1 > 0
)
, "Take Bus"
, (
IF (
(
1 > 0
)
, "Take Bike"
, "Take Taxi"
)
)
) AS ?travelMethod
)
FROM data:
WHERE { ?1 ?2 ?3 }
}
-- 那些内部 (SELECT ?value … LIMIT 1)
查询也会自行验证 --
SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID }
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBusService" }
}
ORDER BY DESC (?time)
LIMIT 1
我相信以下是有效的语法——即使 sparql.org 验证器在其上阻塞——但我不能确定它是否执行,因为我没有时间将查询重新设置为 运行 针对随机端点和数据集。如果您针对 DBpedia 等 运行 修改查询,您可以帮助下一个人!
SELECT ?travelMethod
WHERE
{
SELECT DISTINCT
( IF
(
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID }
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBusService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bus"
, (
IF (
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID }
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBikeService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bike"
, "Take Taxi"
)
)
) AS ?travelMethod
)
FROM data:
WHERE { ?1 ?2 ?3 }
}
花了一点时间离开它,re-reading 你在上面的评论中对你的数据说了什么,我可以进一步优化这个查询,这也可能使它执行得更快 --
SELECT ?travelMethod
WHERE
{
SELECT DISTINCT
( IF
(
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value
; rdf:label "Availability"
; ontology:isObservedValueOf ?obsID
. ?obsID ssn:observationResultTime ?time
; ssn:observedBy ?id
}
GRAPH meta: { ?id rdf:label "MyBusService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bus"
, (
IF (
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value
; rdf:label "Availability"
; ontology:isObservedValueOf ?obsID
. ?obsID ssn:observationResultTime ?time
; ssn:observedBy ?id
}
GRAPH meta: { ?id rdf:label "MyBikeService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bike"
, "Take Taxi"
)
)
) AS ?travelMethod
)
FROM data:
WHERE { ?1 ?2 ?3 }
}
我正在尝试 运行 以下 SPARQL 查询,但它一直在 returning SR171: Transaction timed out
。
SELECT ?isBusAvailable WHERE {
SELECT DISTINCT IF (
(
SELECT ?value2 WHERE {
GRAPH data: { ?obsValueID2 ontology:value ?value2 }
GRAPH data: { ?obsValueID2 rdf:label "Availability" }
GRAPH data: { ?obsValueID2 ontology:isObservedValueOf ?obsID2}
GRAPH data: { ?obsID2 ssn:observationResultTime ?time2 }
GRAPH data: { ?obsID2 ssn:observedBy ?id2 }
GRAPH meta: { ?id2 rdf:label "MyBusService" }
} ORDER BY DESC (?time2) LIMIT 1) > 1, "Take Bus", (
SELECT ?isBikeAvailable WHERE {
SELECT DISTINCT IF (
(
SELECT ?value3 WHERE {
GRAPH data: { ?obsValueID3 ontology:value ?value3 }
GRAPH data: { ?obsValueID3 rdf:label "Availability" }
GRAPH data: { ?obsValueID3 ontology:isObservedValueOf ?obsID3}
GRAPH data: { ?obsID3 ssn:observationResultTime ?time3 }
GRAPH data: { ?obsID3 ssn:observedBy ?id3 }
GRAPH meta: { ?id3 rdf:label "MyBikeService" }
} ORDER BY DESC (?time3) LIMIT 1
) > 0, "Take Bike", "Take Taxi") as ?isBikeAvailable WHERE { ?1 ?2 ?3}})) as ?isBusAvailable WHERE { ?4 ?5 ?6}}
如果我单独 运行 它们,它 运行 不到 1 秒。以下示例有效。
SELECT ?isBusAvailable WHERE {
SELECT DISTINCT IF (
(
SELECT ?value2 WHERE {
GRAPH data: { ?obsValueID2 ontology:value ?value2 }
GRAPH data: { ?obsValueID2 rdf:label "Availability" }
GRAPH data: { ?obsValueID2 ontology:isObservedValueOf ?obsID2}
GRAPH data: { ?obsID2 ssn:observationResultTime ?time2 }
GRAPH data: { ?obsID2 ssn:observedBy ?id2 }
GRAPH meta: { ?id2 rdf:label "MyBusService" }
} ORDER BY DESC (?time2) LIMIT 1) > 1, "Take Bus", 'Take Bike') as ?isBusAvailable WHERE { ?4 ?5 ?6}}
如果第一个查询的结果为真,return 'Take Bus';否则,运行 第二个查询,return 'Take Bike' 或 'Take Taxi'。
显然问题出在第二个查询上(来自第一个查询的错误条件)。在 "Take Bus" 之后,如果我将第二个查询更改为 "Take Bike",它会起作用。
假条件下的查询需要遵循 SPARQL 中 IF 条件语句的格式,因为它 returns 是一个值。删除 "SELECT DISTINCT"
SELECT ?isBusAvailable WHERE {
SELECT DISTINCT (IF(
(
SELECT ?value WHERE {
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID}
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBusService" }
} ORDER BY DESC (?time) LIMIT 1) > 0,'Take Bus', (
IF (
(
SELECT ?value WHERE {
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID}
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBikeService" }
} ORDER BY DESC (?time) LIMIT 1
) > 0, "Take Bike", "Take Taxi")
)) AS ?isBusAvailable) FROM data: WHERE { ?1 ?2 ?3 }}
编辑: select distinct if( ... )
不是合法的 SPARQL,因此 if 语句需要包含在括号中。查询变为:select distinct (if( ... ))
@andrei -- 我认为你的 ?isBusAvailable
混淆了事情 -- 考虑到你最后 return 的字面值,这可能更好 ?travelMethod
。
当我读到东西时,这里的问题实际上是如何正确构造嵌套的 IFs
——问题的标题也许应该是 "What is correct syntax for nesting IF statements in SPARQL?"
在简单流程中,我认为您正在做的是检查可用总线,如果存在,returning "Take bus";如果没有,则检查是否有可用的自行车,如果存在,则 return "Take bike";如果没有,你 return "Take taxi"。在 psuedo-code、IF AVAIL bus, THEN take bus, ELSE ( IF AVAIL bike, THEN take bike, ELSE take taxi )
.
@joshua-taylor 在一件事上是正确的 — SELECT DISTINCT IF (…)
严格来说不是有效的,但修复只是一个额外的 paren 包装器 — 例如,以下是有效的(并验证)— -
SELECT DISTINCT ( IF ( ( 1 = 1 )
, "true"
, "false"
) AS ?test )
WHERE { ?x ?y ?z }
LIMIT 1
但是在您的查询中修复此问题并没有从验证器获得更好的输出。事实上,用 1
替换内部 (SELECT ?value … LIMIT 1)
查询会使整个大型查询有效 -
SELECT ?travelMethod
WHERE
{
SELECT DISTINCT
( IF
(
(
1 > 0
)
, "Take Bus"
, (
IF (
(
1 > 0
)
, "Take Bike"
, "Take Taxi"
)
)
) AS ?travelMethod
)
FROM data:
WHERE { ?1 ?2 ?3 }
}
-- 那些内部 (SELECT ?value … LIMIT 1)
查询也会自行验证 --
SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID }
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBusService" }
}
ORDER BY DESC (?time)
LIMIT 1
我相信以下是有效的语法——即使 sparql.org 验证器在其上阻塞——但我不能确定它是否执行,因为我没有时间将查询重新设置为 运行 针对随机端点和数据集。如果您针对 DBpedia 等 运行 修改查询,您可以帮助下一个人!
SELECT ?travelMethod
WHERE
{
SELECT DISTINCT
( IF
(
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID }
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBusService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bus"
, (
IF (
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value }
GRAPH data: { ?obsValueID rdf:label "Availability" }
GRAPH data: { ?obsValueID ontology:isObservedValueOf ?obsID }
GRAPH data: { ?obsID ssn:observationResultTime ?time }
GRAPH data: { ?obsID ssn:observedBy ?id }
GRAPH meta: { ?id rdf:label "MyBikeService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bike"
, "Take Taxi"
)
)
) AS ?travelMethod
)
FROM data:
WHERE { ?1 ?2 ?3 }
}
花了一点时间离开它,re-reading 你在上面的评论中对你的数据说了什么,我可以进一步优化这个查询,这也可能使它执行得更快 --
SELECT ?travelMethod
WHERE
{
SELECT DISTINCT
( IF
(
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value
; rdf:label "Availability"
; ontology:isObservedValueOf ?obsID
. ?obsID ssn:observationResultTime ?time
; ssn:observedBy ?id
}
GRAPH meta: { ?id rdf:label "MyBusService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bus"
, (
IF (
(
( SELECT ?value
WHERE
{
GRAPH data: { ?obsValueID ontology:value ?value
; rdf:label "Availability"
; ontology:isObservedValueOf ?obsID
. ?obsID ssn:observationResultTime ?time
; ssn:observedBy ?id
}
GRAPH meta: { ?id rdf:label "MyBikeService" }
}
ORDER BY DESC (?time)
LIMIT 1
) > 0
)
, "Take Bike"
, "Take Taxi"
)
)
) AS ?travelMethod
)
FROM data:
WHERE { ?1 ?2 ?3 }
}