Jay Gray
Jay Gray

Reputation: 1726

Wikidata SPARQL: how to filter by date range?

This query finds winners of the Nobel Prize for Chemistry.

SELECT DISTINCT ?item ?itemLabel ?when (YEAR(?when) as ?date)
WHERE {
  ?item p:P166 ?awardStat .
  ?awardStat ps:P166 wd:Q44585 .
  ?awardStat pq:P585 ?when .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
}

See it here

Now would like to find chemistry prize winners in a period of time (date range).

One approach might be to search for each target year (each point in time P585) and then concatenate the results.

But a better approach might be to filter the result set from above. For example, filter where the earliest ?date is "2014" and the latest ?date is "2017"

However, this filter fails:

SELECT DISTINCT ?item ?itemLabel ?when (YEAR(?when) as ?date)
WHERE {
  ?item p:P166 ?awardStat .
  ?awardStat ps:P166 wd:Q44585 .
  ?awardStat pq:P585 ?when .
FILTER(?date <= "2017"^^pq:P585 && ?date > "2014"^^pq:P585)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
}

My thought was to specify the string "2014" as a qualifier for point in time but that didn't work.

How to modify the Wikidata SPARQL query to find/filter results between two points in time?

Upvotes: 2

Views: 2410

Answers (1)

Jay Gray
Jay Gray

Reputation: 1726

Based on (always high quality) advice from AKSW the best way to select items with dates that occur in a range of dates is as follows:

SELECT DISTINCT ?item ?itemLabel ?when (YEAR(?when) as ?date)
WHERE {
  ?item p:P166 ?awardStat .
  ?awardStat ps:P166 wd:Q44585 . 
  ?awardStat pq:P585 ?when . 
FILTER(YEAR(?when) <= 2017 && YEAR(?when) > 2014)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
}

an alternative is to use BIND with FILTER

SELECT DISTINCT ?item ?itemLabel ?when (YEAR(?when) as ?date)
WHERE {
  ?item p:P166 ?awardStat .
  ?awardStat ps:P166 wd:Q44585 . 
  ?awardStat pq:P585 ?when . 
BIND(YEAR(?when) as ?date) FILTER(?date <= 2017 && ?date > 2014)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
}

The solution uses point in time P585. An alternative solution could use start time (P580) and end time (P582), or start period (P3415) end period (P3416). Those properties are used to qualify periods-of-time in many Wikidata items.

Wikidata does define years, such as 2014 (Q1999) and 2017 (Q25290). But years are not used by most Wikidata items to qualify a period-of-time. So we have to use (YEAR(?when) as the method to set ?date and then FILTER on ?date

Upvotes: 1

Related Questions