简体   繁体   中英

SPARQL query gives different result as a subquery

When running the following query I get only one result as expected

SELECT DISTINCT ?city ?country WHERE {
  FILTER (?city = wd:Q1748) .

  # Primary country
  ?city p:P17 ?c .
  ?c ps:P17 ?country ;
     wikibase:rank ?rank .
  FILTER NOT EXISTS { ?c pq:P582 [] . } # Existing countries only
  FILTER NOT EXISTS {
    ?city p:P17 [ wikibase:rank ?rank2 ] .
    FILTER (?rank2 = wikibase:PreferredRank && ?rank != wikibase:PreferredRank) .
  }
  FILTER (?rank != wikibase:DeprecatedRank) .
}

However, I get two results if I query the same code as a subquery:

SELECT * WHERE {
  {
    SELECT DISTINCT ?city ?country WHERE {
      FILTER (?city = wd:Q1748) .

      # Primary country
      ?city p:P17 ?c .
      ?c ps:P17 ?country ;
         wikibase:rank ?rank .
      FILTER NOT EXISTS { ?c pq:P582 [] . } # Existing countries only
      FILTER NOT EXISTS {
        ?city p:P17 [ wikibase:rank ?rank2 ] .
        FILTER (?rank2 = wikibase:PreferredRank && ?rank != wikibase:PreferredRank) .
      }
      FILTER (?rank != wikibase:DeprecatedRank) .
    }
  }
}

According to the documentation the subquery is executed first and the result is then transferred to the outer query, so why does SELECT * not give the same result?

As explained in the Wikidata documentation here :

The “filter not exists” clause seems to often be inefficient for unclear reasons. To work fine, queries with “filter not exists” often seem to have to be rewritten.

I modified your query and now both queries return the same results:

SELECT * WHERE {
  {
    SELECT DISTINCT ?city ?country WHERE {
      FILTER (?city = wd:Q1748) .

      # Primary country
      ?city p:P17 ?c .
      ?c ps:P17 ?country ;
         wikibase:rank ?rank .
      FILTER NOT EXISTS { ?c pq:P582 [] . } # Existing countries only
      OPTIONAL {?city p:P17 [ wikibase:rank ?rank2 ] .}
      FILTER (?rank2 = wikibase:PreferredRank && ?rank != wikibase:PreferredRank) .
      FILTER (?rank != wikibase:DeprecatedRank) .
    }
  }
}

I also checked the ranks of p17 using the following query and wikibase:DeprecatedRank is not the results:

SELECT * WHERE {
wd:Q1748 p:P17 ?o. ?o ?p ?q.
}

wd:Q35 wikibase:PreferredRank
wd:Q756617 wikibase:NormalRank

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM