Subqueries, VALUES, and BIND

Compose queries, inject inline data, and compute columns.

0/2 done

Theory

Three composition tools turn flat queries into professional ones.

Sub-SELECT — a full query nested in a { }; its results join with the outer pattern. Essential because aggregation happens inside the subquery, then you filter/join on the aggregate outside:

SELECT ?master ?students WHERE {
  { SELECT ?master (COUNT(?n) AS ?students) WHERE {
      ?master :teaches ?n .
    } GROUP BY ?master }
  FILTER(?students > 1)
}

Evaluation is inside-out: the inner query runs first and only its projected variables are visible outside.

VALUES — inline a table of constants to constrain or drive a query (also how parameterised clients bind inputs safely):

SELECT ?ninja WHERE {
  ?ninja a ?type .
  VALUES ?type { :Ninja :Master }
}

BIND — compute a new column from an expression:

BIND(CONCAT(?first, " ", ?last) AS ?fullName)

Remember the division of labour from the FILTER lesson: FILTER removes rows, BIND adds a computed variable, VALUES supplies fixed input rows.

Worked example — compare against an average

Worked example — 'masters teaching more than the average'.

This needs an aggregate compared against another aggregate, which is impossible in one flat query — subqueries make it natural:

SELECT ?master ?students WHERE {
  { SELECT ?master (COUNT(?n) AS ?students) WHERE {
      ?master :teaches ?n .
    } GROUP BY ?master }
  { SELECT (AVG(?c) AS ?avg) WHERE {
      SELECT (COUNT(?n) AS ?c) WHERE { ?m :teaches ?n . } GROUP BY ?m
    } }
  FILTER(?students > ?avg)
}

The inner subqueries each produce one aggregate; the outer query joins them and filters. This 'aggregate vs aggregate' shape is the canonical reason subqueries exist.

Reading in progress · 0 of 2 activities done