Filter skyscrapers higher than 500 meters in Wikid

2019-07-28 10:24发布

问题:

I try to construct a SPARQL query, where I get a list of skyscrapers with a height of more then 500 meters.

I realized, that the property height (P2048) is measured in different units (meter, foot, centimeter). This would not be a problem for me to calculate the different units into meters.

But my problem is to figure out, that unit is used for the property height.

So my question: how can I get the unit for the property height?

My query so far, where ?unit is just empty:

SELECT ?skyscraper ?skyscraperLabel ?height ?unit WHERE {
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
  ?skyscraper wdt:P31 wd:Q11303.
  ?skyscraper wdt:P2048 ?height.
  FILTER(?height > 500)
  OPTIONAL { ?skyscraper wdt:P2876 ?unit. }
}
LIMIT 100

Try it here

回答1:

To get the unit itelf use :P2048/psv:P2048/wikibase:quantityUnit:

SELECT ?skyscraper ?skyscraperLabel ?height ?unit ?unitLabel WHERE {
  ?skyscraper wdt:P31 wd:Q11303.
  ?skyscraper p:P2048/psv:P2048 ?vn.
  ?vn wikibase:quantityAmount ?height.
  ?vn wikibase:quantityUnit ?unit.  
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
LIMIT 100

Try it here

However, following AKSW and Stanislav Kralin's comments above, it is better to use Normalized values using the psn: prefix: p:P2048/psn:P2048/wikibase:quantityAmount:

SELECT ?skyscraper ?skyscraperLabel ?height WHERE {
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
  ?skyscraper wdt:P31 wd:Q11303.
  ?skyscraper p:P2048/psn:P2048/wikibase:quantityAmount ?height.
  FILTER(?height >= 500)
}
ORDER BY DESC(?height)
LIMIT 1000

Try this here

Since some buildings contains multiple height values (for example, One World Trade Center have both architectural height (Q24192182) and height to pinnacle (Q26970842) values), some aggregation is needed to retrieve one value per building in SPARQL:

SELECT ?skyscraper ?skyscraperLabel (MAX(?h) AS ?height) WHERE {
  ?skyscraper wdt:P31 wd:Q11303.
  ?skyscraper p:P2048/psn:P2048/wikibase:quantityAmount ?h.
  FILTER(?h >= 500)
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
GROUP BY ?skyscraper ?skyscraperLabel
ORDER BY DESC(?height)
LIMIT 1000

Try it here