Data Model

Data model for Zürich datasets

The Zürich Statistical Office collects data on the city and its residents. This data is published as Linked Data.

In this tutorial, we will explain the linked data model behind it. Mainly, we will guide you through the data structure. The tutorial will show you available datasets, and the shape they take. We will look into queries explaining the data structure as well as available dimensions.

SPARQL endpoint

Data by the Zürich Statistical Office is published as Linked Data. It can be accessed with SPARQL queries. You can send queries using HTTP requests. The API endpoint is https://ld.stadt-zuerich.ch/query.

We use the SPARQL kernel in a jupyter notebook to communicate with the database (you may need to configure this via menu Kernel -> Change kernel -> SPARQL). First, let's configure the endpoint.

In [1]:
#Params
%endpoint https://ld.stadt-zuerich.ch/query
%auth basic public public
%display table

%show 50
Endpoint set to: https://ld.stadt-zuerich.ch/query
HTTP authentication: method=basic, user=public, passwd set
Display: table
Result maximum size: 50

Graphs

One endpoint can contain multiple named graphs.

You can see what graphs are available using WHERE and GRAPH statements.

These graphs have potentilly nothing in common, they are simply stored in the same database.

Here, we have one endpoint storing information on subject as diverse as the train timetable, electricity prices, or animal diseases:

All those graphs can be accessed from the same SPARQL endpoint.

Graph by Zürich Statistical Office

Datasets from the Zürich Statistical Office are published in the following named graph: <https://lindas.admin.ch/stadtzuerich/stat>

You can limit your queries to one named graph using WHERE and FROM statements.

Data cubes

Datasets published by Zürich Statistial Office are stored as data cubes. Let's check the cube definition in its documentation:

Cube
Represents the entry point for a collection of observations, conforming to some common dimensional structure.

We can find all data cubes by defining <https://cube.link/Cube> as object.

In [4]:
# List all data cubes

SELECT ?cubes
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?cubes a <https://cube.link/Cube> .
}
cubes
https://ld.stadt-zuerich.ch/statistics/WHG
https://ld.stadt-zuerich.ch/statistics/WHA-ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM-WHA
https://ld.stadt-zuerich.ch/statistics/WHA
https://ld.stadt-zuerich.ch/statistics/APZ
https://ld.stadt-zuerich.ch/statistics/WHG-ZIM
https://ld.stadt-zuerich.ch/statistics/BEW
https://ld.stadt-zuerich.ch/statistics/BEW-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/ANT-GGH-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/GES-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/GES-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/AST-BTA
https://ld.stadt-zuerich.ch/statistics/TIA-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/WRT-BTA-EAP
https://ld.stadt-zuerich.ch/statistics/TII-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/TII-BTA
https://ld.stadt-zuerich.ch/statistics/TIA-BTA
https://ld.stadt-zuerich.ch/statistics/AST-BEW-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-HEL
https://ld.stadt-zuerich.ch/statistics/BES-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/BES-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-ZSA
https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM
Total: 34, Shown: 34

All cubes have the same data structure. This means we can write very similar queries to get data from different cubes.

Data cubes have the following properties:

In [5]:
# Cube properties

SELECT DISTINCT ?properties
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?s a <https://cube.link/Cube> ;
    ?properties ?o.
}

Let's learn more about available data cubes. We can access cube description using <http://schema.org/name> property. We will also get its id using <http://schema.org/identifier>. By defining schema and cube as PREFIX, we can save some typing.

In [6]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT *
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?cube a cube:Cube ;
       schema:name ?description ;
       schema:identifier ?id .
}
cube description id
https://ld.stadt-zuerich.ch/statistics/WHG Statistische Wohnungen WHG
https://ld.stadt-zuerich.ch/statistics/WHG Statistische Wohnungen nach Zeit WHG
https://ld.stadt-zuerich.ch/statistics/WHA-ZIM Wohnungen (ohne Appartements) nach Zeit, Zimmerzahl einer Wohnung WHA-ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM Zimmer ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM Zimmer nach Zeit ZIM
https://ld.stadt-zuerich.ch/statistics/ZIM-WHA Zimmer nach Zeit, Wohnungsart ZIM-WHA
https://ld.stadt-zuerich.ch/statistics/WHA Wohnungen (ohne Appartements) WHA
https://ld.stadt-zuerich.ch/statistics/WHA Wohnungen (ohne Appartements) nach Zeit WHA
https://ld.stadt-zuerich.ch/statistics/APZ Appartementzimmer APZ
https://ld.stadt-zuerich.ch/statistics/APZ Appartementzimmer nach Zeit APZ
https://ld.stadt-zuerich.ch/statistics/WHG-ZIM Statistische Wohnungen nach Zeit, Zimmerzahl einer Wohnung WHG-ZIM
https://ld.stadt-zuerich.ch/statistics/BEW Wirtschaftliche Wohnbevölkerung BEW
https://ld.stadt-zuerich.ch/statistics/BEW Wirtschaftliche Wohnbevölkerung nach Zeit BEW
https://ld.stadt-zuerich.ch/statistics/BEW-SEX Wirtschaftliche Wohnbevölkerung nach Geschlecht, Zeit BEW-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX Wirtschaftliche Wohnbevölkerung nach Heimatland, Geschlecht, Zeit BEW-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/ANT-GGH-HEL Anteil nach Grundgesamtheit, Heimatland, Zeit ANT-GGH-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-HEL Wirtschaftliche Wohnbevölkerung nach Heimatland, Zeit BEW-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT Wirtschaftliche Wohnbevölkerung nach Alter, Zeit BEW-ALT
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX-TOU Sterbefälle (wirtschaftlich) nach Alter, Geschlecht, Zeit, Todesursachen GES-ALT-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/GES-SEX-TOU Sterbefälle (wirtschaftlich) nach Geschlecht, Zeit, Todesursachen GES-SEX-TOU
https://ld.stadt-zuerich.ch/statistics/GES-ALT-SEX Sterbefälle (wirtschaftlich) nach Alter, Geschlecht, Zeit GES-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/GES-SEX Sterbefälle (wirtschaftlich) nach Geschlecht, Zeit GES-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL-SEX Wirtschaftliche Wohnbevölkerung nach Alter, Heimatland, Geschlecht, Zeit BEW-ALT-HEL-SEX
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-HEL Wirtschaftliche Wohnbevölkerung nach Alter, Heimatland, Zeit BEW-ALT-HEL
https://ld.stadt-zuerich.ch/statistics/BEW-ALT-SEX Wirtschaftliche Wohnbevölkerung nach Alter, Geschlecht, Zeit BEW-ALT-SEX
https://ld.stadt-zuerich.ch/statistics/AST-BTA Arbeitsstätten nach Betriebsart, Zeit AST-BTA
https://ld.stadt-zuerich.ch/statistics/TIA-BTA-TIG Tierarten nach Betriebsart, Tiergattung, Zeit TIA-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/WRT-BTA-EAP Wert nach Betriebsart, Erfolgsrechnung, Zeit WRT-BTA-EAP
https://ld.stadt-zuerich.ch/statistics/TII-BTA-TIG Tierindividuen nach Betriebsart, Tiergattung, Zeit TII-BTA-TIG
https://ld.stadt-zuerich.ch/statistics/TII-BTA Tierindividuen nach Betriebsart, Zeit TII-BTA
https://ld.stadt-zuerich.ch/statistics/TIA-BTA Tierarten nach Betriebsart, Zeit TIA-BTA
https://ld.stadt-zuerich.ch/statistics/AST-BEW-BTA Arbeitsstätten nach Bewilligung, Betriebsart, Zeit AST-BEW-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-SEX Zuschauer/innen, Besucher/innen nach Betriebsart, Geschlecht, Zeit ZUS-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA Zuschauer/innen, Besucher/innen nach Betriebsart, Zeit ZUS-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-HEL Zuschauer/innen, Besucher/innen nach Betriebsart, Heimatland, Zeit ZUS-BTA-HEL
https://ld.stadt-zuerich.ch/statistics/BES-BTA-SEX Beschäftigte nach Betriebsart, Geschlecht, Zeit BES-BTA-SEX
https://ld.stadt-zuerich.ch/statistics/BES-BTA Beschäftigte nach Betriebsart, Zeit BES-BTA
https://ld.stadt-zuerich.ch/statistics/ZUS-BTA-ZSA Zuschauer/innen, Besucher/innen nach Betriebsart, Zeit, Zuschauer- bzw. Besucherart ZUS-BTA-ZSA
https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM Quadratmeterpreis nach Eigentümerart, Handänderungsart, Objektart, Zeit, Zimmerzahl einer Wohnung QMP-EIG-HAA-OBJ-ZIM
Total: 39, Shown: 39

You can see that some cubes have more than one description.

Observation set

Observations in data cubes are stored in observation set (<https://cube.link/observationSet>). Let's check the observationSet definition in its documentation:

observationSet
Connects a cube with a set of observations.

We can find all observations in a cube using cube:observationSet/cube:observation as predicate. Let's query all observations in <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> cube.

We can count the number of observations using COUNT statement

In [8]:
# Count observations in a data cube

PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT (COUNT(?obs) AS ?count)
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
           cube:observationSet/cube:observation ?obs.
    # Equivalent to:
    #       cube:observationSet ?observationSet.
    #?observationSet cube:observation ?obs.
}
count
9512
Total: 1, Shown: 1

So in BEW-HEL-SEX cube we have almost 10k observations about the population of Zürich!

Observations

Let's take a closer look at the observations. We can get all observation properties using this query:

In [9]:
# Observation properties

PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT DISTINCT ?obsProperty
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  ?dataset a cube:Cube;
             cube:observationSet/cube:observation ?observation. 
    ?observation ?obsProperty ?obsVal.
}
obsProperty
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
https://ld.stadt-zuerich.ch/statistics/property/ZEIT
https://ld.stadt-zuerich.ch/statistics/property/RAUM
https://ld.stadt-zuerich.ch/statistics/attribute/KORREKTUR
https://ld.stadt-zuerich.ch/statistics/measure/WHG
http://schema.org/identifier
https://cube.link/observedBy
https://ld.stadt-zuerich.ch/statistics/property/TIME
https://ld.stadt-zuerich.ch/statistics/property/ZIM
https://ld.stadt-zuerich.ch/statistics/measure/WHA
https://ld.stadt-zuerich.ch/statistics/measure/ZIM
https://ld.stadt-zuerich.ch/statistics/property/WHA
https://ld.stadt-zuerich.ch/statistics/measure/APZ
https://ld.stadt-zuerich.ch/statistics/measure/BEW
https://ld.stadt-zuerich.ch/statistics/property/SEX
https://ld.stadt-zuerich.ch/statistics/property/HEL
https://ld.stadt-zuerich.ch/statistics/property/GGH
https://ld.stadt-zuerich.ch/statistics/measure/ANT
https://ld.stadt-zuerich.ch/statistics/property/ALT
https://ld.stadt-zuerich.ch/statistics/measure/GES
https://ld.stadt-zuerich.ch/statistics/property/TOU
https://ld.stadt-zuerich.ch/statistics/property/BTA
https://ld.stadt-zuerich.ch/statistics/measure/AST
https://ld.stadt-zuerich.ch/statistics/property/TIG
https://ld.stadt-zuerich.ch/statistics/measure/TIA
https://ld.stadt-zuerich.ch/statistics/measure/WRT
https://ld.stadt-zuerich.ch/statistics/property/EAP
https://ld.stadt-zuerich.ch/statistics/measure/TII
https://ld.stadt-zuerich.ch/statistics/property/BEW
https://ld.stadt-zuerich.ch/statistics/measure/ZUS
https://ld.stadt-zuerich.ch/statistics/measure/BES
https://ld.stadt-zuerich.ch/statistics/property/ZSA
https://ld.stadt-zuerich.ch/statistics/property/OBJ
https://ld.stadt-zuerich.ch/statistics/property/EIG
https://ld.stadt-zuerich.ch/statistics/property/HAA
https://ld.stadt-zuerich.ch/statistics/measure/QMP
Total: 36, Shown: 36

Quite a bit! Now, not every dataset will have all those properties.

Let's get a list of properties for the <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> data cube. We will also get its labels using schema:name, and descrption using schema:description.

Since not all properties have a description, we will use the OPTIONAL statement to query it.

In [10]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT DISTINCT ?obsProperty ?label ?description 
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?observation. 
    ?observation ?obsProperty ?obsVal.
    ?obsProperty schema:name ?label .
    OPTIONAL {
        ?obsProperty schema:description ?description .
    }
}
obsProperty label description
https://ld.stadt-zuerich.ch/statistics/property/ZEIT Zeit Repräsentation der Zeit als Konzept, repräsentiert die vollständige Komplexität.
https://ld.stadt-zuerich.ch/statistics/property/RAUM Raum
https://ld.stadt-zuerich.ch/statistics/measure/BEW Wirtschaftliche Wohnbevölkerung Wirtschaftliche Wohnbevölkerung
https://ld.stadt-zuerich.ch/statistics/property/HEL Heimatland
https://ld.stadt-zuerich.ch/statistics/property/SEX Geschlecht
https://ld.stadt-zuerich.ch/statistics/property/TIME Zeit Repräsentation der Zeit als ISO 8601 Datum (vereinfacht).
Total: 6, Shown: 6

We can see that BEW-HEL-SEX data cube contains data on the population across:

  • time (german: Zeit)
  • place (german: Raum)
  • gender (german: Geschlecht)
  • origin (german: Heimatland)

Knowing properties, we can directlty query the measurements. Now, we are able to find the actual data: number of inhabitants across time, place, gender, and origin.

We will find the measurements using <https://ld.stadt-zuerich.ch/statistics/measure/BEW> as the observation's property. We will also the cube's dimensions using:

  • <https://ld.stadt-zuerich.ch/statistics/property/RAUM> for place
  • <https://ld.stadt-zuerich.ch/statistics/property/TIME> for time
  • <https://ld.stadt-zuerich.ch/statistics/property/HEL> for origin
  • <https://ld.stadt-zuerich.ch/statistics/property/SEX> for gender

And again, making use of PREFIX makes the query more readable.

In [11]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?origin ?gender ?count
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:RAUM ?place ;
                 property:TIME ?time ;
                 property:HEL ?origin ;
                 property:SEX ?gender .
    
}
LIMIT 10
time place origin gender count
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00012 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 94.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00013 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 157.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00014 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 267.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00024 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 1686.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00033 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 4694.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00042 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 1709.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00044 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 2687.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00052 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0001 2256.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00072 https://ld.stadt-zuerich.ch/statistics/code/HEL2000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 1613.0
2017-12-31 https://ld.stadt-zuerich.ch/statistics/code/R00074 https://ld.stadt-zuerich.ch/statistics/code/HEL1000 https://ld.stadt-zuerich.ch/statistics/code/SEX0002 4453.0
Total: 10, Shown: 10

To make the output more readable, let's replace the IRIs with the corresponding labels. This can be achieved by using schema:name for each property.

In [12]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?origin ?gender ?count
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:RAUM/schema:name ?place ;
                 property:TIME  ?time ;
                 property:HEL/schema:name  ?origin ;
                 property:SEX/schema:name  ?gender .
    
}
LIMIT 10
time place origin gender count
2017-12-31 Hochschulen Ausland weiblich 94.0
2017-12-31 Lindenhof Ausland männlich 157.0
2017-12-31 City Schweiz weiblich 267.0
2017-12-31 Enge Ausland weiblich 1686.0
2017-12-31 Friesenberg Schweiz weiblich 4694.0
2017-12-31 Langstrasse Ausland weiblich 1709.0
2017-12-31 Hard Ausland männlich 2687.0
2017-12-31 Escher Wyss Schweiz männlich 2256.0
2017-12-31 Hottingen Ausland weiblich 1613.0
2017-12-31 Witikon Schweiz weiblich 4453.0
Total: 10, Shown: 10

Volià! We now got all measurements across all dimensions in the BEW-ALT-SEX data cube. The data could be further refined, for example by filtering on gender or place.

Let's do the same exercise for the QMP-EIG-HAA-OBJ-ZIM data cube.

First, let's get observations' properties.

In [13]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>

SELECT DISTINCT ?obsProperty ?label ?description 
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM> a cube:Cube;
             cube:observationSet/cube:observation ?observation. 
    ?observation ?obsProperty ?obsVal.
    ?obsProperty schema:name ?label .
    OPTIONAL {
        ?obsProperty schema:description ?description .
    }
}
obsProperty label description
https://ld.stadt-zuerich.ch/statistics/property/ZEIT Zeit Repräsentation der Zeit als Konzept, repräsentiert die vollständige Komplexität.
https://ld.stadt-zuerich.ch/statistics/property/RAUM Raum
https://ld.stadt-zuerich.ch/statistics/property/ZIM Zimmerzahl einer Wohnung
https://ld.stadt-zuerich.ch/statistics/property/OBJ Objektart
https://ld.stadt-zuerich.ch/statistics/property/EIG Eigentümerart
https://ld.stadt-zuerich.ch/statistics/property/HAA Handänderungsart
https://ld.stadt-zuerich.ch/statistics/measure/QMP Quadratmeterpreis Preis in Franken pro Quadratmeter
https://ld.stadt-zuerich.ch/statistics/property/TIME Zeit Repräsentation der Zeit als ISO 8601 Datum (vereinfacht).
Total: 8, Shown: 8

Now, let's use these properties to query the data.

In [14]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?rooms ?ownership ?haa ?type ?price
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM> a cube:Cube;
             cube:observationSet/cube:observation ?obs . 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/QMP> ?price ;
                 property:TIME  ?time ;
                 property:RAUM/schema:name ?place ;
                 property:ZIM/schema:name  ?rooms ;
                 property:EIG/schema:name  ?ownership ;
                 property:HAA/schema:name  ?market ;
                 property:OBJ/schema:name  ?type .
    
}
LIMIT 10
time place rooms ownership haa type price
2017-12-31 Werd 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Weinegg 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Langstrasse 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Albisrieden 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Rathaus 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Hard 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2017-12-31 Seebach 8- und mehr-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
2009-12-31 Rathaus 1- und 1,5-Zimmer Wohnung Stockwerkeigentum Wohnung 16724.0
2009-12-31 Rathaus 2- und 2,5-Zimmer Wohnung Stockwerkeigentum Wohnung 13603.0
2009-12-31 Rathaus 3- und 3,5-Zimmer Wohnung Stockwerkeigentum Wohnung 0.0
Total: 10, Shown: 10

You can see that some prices come back as zero. Getting an appartment for free is extremely rare in Switzerland. That's presumably a data issue.

Let's remove those invalid observations using a FILTER statement.

In [15]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?rooms ?ownership ?haa ?type ?price
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/QMP-EIG-HAA-OBJ-ZIM> a cube:Cube;
             cube:observationSet/cube:observation ?obs . 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/QMP> ?price ;
                 property:TIME  ?time ;
                 property:RAUM/schema:name ?place ;
                 property:ZIM/schema:name  ?rooms ;
                 property:EIG/schema:name  ?ownership ;
                 property:HAA/schema:name  ?market ;
                 property:OBJ/schema:name  ?type .
    FILTER (?price > 0)  
}
LIMIT 10
time place rooms ownership haa type price
2009-12-31 Rathaus 1- und 1,5-Zimmer Wohnung Stockwerkeigentum Wohnung 16724.0
2009-12-31 Rathaus 2- und 2,5-Zimmer Wohnung Stockwerkeigentum Wohnung 13603.0
2009-12-31 Lindenhof 1- und 1,5-Zimmer Wohnung Stockwerkeigentum Wohnung 7083.0
2009-12-31 Lindenhof 2- und 2,5-Zimmer Wohnung Stockwerkeigentum Wohnung 10625.0
2009-12-31 Wollishofen 1- und 1,5-Zimmer Wohnung Stockwerkeigentum Wohnung 8315.0
2009-12-31 Wollishofen 2- und 2,5-Zimmer Wohnung Stockwerkeigentum Wohnung 11417.0
2009-12-31 Wollishofen 3- und 3,5-Zimmer Wohnung Stockwerkeigentum Wohnung 11263.0
2009-12-31 Wollishofen 4- und 4,5-Zimmer Wohnung Stockwerkeigentum Wohnung 6865.0
2009-12-31 Wollishofen 5- und 5,5-Zimmer Wohnung Stockwerkeigentum Wohnung 11486.0
2009-12-31 Wollishofen 6- und 6,5-Zimmer Wohnung Stockwerkeigentum Wohnung 4214.0
Total: 10, Shown: 10

That's better!

Data slices

Thus far, we queried all observations from the data cube. Sometimes, you are interested in just some of the dimensions. You can aggregate the results using GROUP BY and SUM statements.

Let's find the total number of people in Zurich accross property:TIME. To do this, we sum the remaining dimensions:

  • property:RAUM
  • property:HEL
  • property:SEX

This can be achieved by leaving them out of the GROUP BY statement. All unmentioned variables will be aggregated.

In [16]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time (SUM(?count) AS ?aggCount)
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:TIME  ?time .
    
}
GROUP BY ?time
LIMIT 10
time aggCount
1920-12-31 206273.0
1921-12-31 200873.0
1922-12-31 199567.0
1923-12-31 202949.0
1924-12-31 205202.0
1925-12-31 207399.0
1926-12-31 212571.0
1927-12-31 217734.0
1928-12-31 227081.0
1929-12-31 236267.0
Total: 10, Shown: 10

You can also filter the results to include only one dimension. This can be done by setting the object to the value you are interested in.

Let's get the number of female inhabitants over time. First, we will find IRIs for gender.

In [17]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT DISTINCT ?genderIRI ?gender
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs property:SEX ?genderIRI.
    ?obs property:SEX/schema:name ?gender .
    
}

<https://ld.stadt-zuerich.ch/statistics/code/SEX0002> stands for female (german weiblich). We will use it to filter observations for female only.

In SPARQL, this can be done by setting observation predicate to property:SEX, and its object to <https://ld.stadt-zuerich.ch/statistics/code/SEX0002>.

In [18]:
PREFIX schema: <http://schema.org/>
PREFIX cube: <https://cube.link/>
PREFIX property: <https://ld.stadt-zuerich.ch/statistics/property/>

SELECT ?time ?place ?origin ?count
FROM <https://lindas.admin.ch/stadtzuerich/stat>
WHERE {
  <https://ld.stadt-zuerich.ch/statistics/BEW-HEL-SEX> a cube:Cube;
             cube:observationSet/cube:observation ?obs. 
    
    ?obs <https://ld.stadt-zuerich.ch/statistics/measure/BEW> ?count ;
                 property:RAUM/schema:name ?place ;
                 property:TIME  ?time ;
                 property:HEL/schema:name  ?origin ;
                 property:SEX  <https://ld.stadt-zuerich.ch/statistics/code/SEX0002> .
    
} 
LIMIT 10
time place origin count
2017-12-31 Hochschulen Ausland 94.0
2017-12-31 City Schweiz 267.0
2017-12-31 Enge Ausland 1686.0
2017-12-31 Friesenberg Schweiz 4694.0
2017-12-31 Langstrasse Ausland 1709.0
2017-12-31 Hottingen Ausland 1613.0
2017-12-31 Witikon Schweiz 4453.0
2017-12-31 Weinegg Ausland 812.0
2017-12-31 Oerlikon Ausland 4049.0
2017-12-31 Saatlen Schweiz 3063.0
Total: 10, Shown: 10

Volià, the number of female inhabitants across time, origin, and city district.

SPEX

There are many ways to learn about the structure of linked data. SPARQL queries may seem dense at first and may take some time to get you to the right place. However, as you get better with SPARQL, they are a great tool to slice data.

Another way to discover linked data is SPEX, a web based tool that visualizes the structure of a linked data source.

SPEX