← every query · class 09 · queries/q4-customers-by-category-last-month.rq

Q4 · Which customers ordered peripherals last month?

The same answer in both regimes: this query asks only for what was written.

?customer?customerName?country?date
customer:4"Papelaria Central"—"2026-10-12"^^xsd:date

The query

# Q4. Which customers ordered products of category X last month?
# X = category:peripherals. "Last month" is October 2026: the reference date is
# written into the query so that the result is reproducible. In a service one
# would use NOW() and a relative interval.
PREFIX schema:   <https://schema.org/>
PREFIX xsd:      <http://www.w3.org/2001/XMLSchema#>
PREFIX onto:     <https://data.csoares.me/onto#>
PREFIX category: <https://data.csoares.me/category/>

# DISTINCT: a customer with two matching orders would otherwise appear twice
SELECT DISTINCT ?customer ?customerName ?country ?date
WHERE {
  ?order a onto:Order ;
         onto:hasCustomer ?customer ;
         onto:date ?date ;
         onto:containsProduct ?p .

  ?p schema:category category:peripherals .
  ?customer schema:name ?customerName .

  # The customers in this graph have no country yet. In an OPTIONAL that only
  # leaves ?country empty; as a plain pattern it would remove every row.
  OPTIONAL { ?customer onto:country ?country }

  # a typed literal: "..."^^xsd:date compares as a date, not as text
  FILTER (?date >= "2026-10-01"^^xsd:date && ?date < "2026-11-01"^^xsd:date)
}
ORDER BY ?customerName

Edit it in the query box →