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 }
     }