

Eric Prud'hommeaux, RDF Data Access Working Group team contact
http://www.w3.org/2007/Talks/0424-spasql/
http://tinyurl.com/39sp65
A pharmaceutical company does a query joining
Save $1,000,000 / day with early termination.
Making queries like:
SELECT ?billCity ?billState
WHERE { ?order <Orders.customer> ?cust .
?cust <Customers.billingAddress> ?addr .
?addr <Addresses.city> ?billCity .
?addr <Addresses.state> ?billState }
on data like:
| id | customer | product | orderDate | shippingAddress |
|---|---|---|---|---|
| 2186 | 518 | 7385 | 2006-05-01 01:08:30 | NULL |
| 2186 | 208 | 2922 | 2006-05-01 18:34:38 | NULL |
| 2187 | 518 | 7439 | 2006-05-01 01:05:30 | NULL |
| givenName | familyName | billingAddress |
|---|---|---|
| Bob | Smith | 18 |
(simple one-database example)
Basis in URIs means everything is globally identifiable...
<http://service1.example/A23D5F> more useful "A23D5F"
and distinct from <http://service1.example/CAD232>
rdf:type
<http://en-dictionary.example/chat> more useful "chat"
and distinct from <http://fr-dictionary.example/chat>
XML: query element/attribute structure.
<Person name="Sue"><knows><Person name="Bob">...</Person></name></Person>
<Person id="p7"><name>Sue</name>...</Person>
<Person id="p23"><name>Bob</name>...</Person>
<knows who="p7" whom="p23"/>
<knows who="p7" whom="..."/>
Relational: tuples of attributes
RDF: relationships between objects.
XQuery: query element/attribute structure.
let $pairs := //knows let $n1 := Person/@name[@id=$pairs/@who] let $n2 := Person/@name[@id=$pairs/@whom]
SQL: query attributes of objects
FROM knows
JOIN Persons as who ON knows.who=who.id
JOIN Persons as whom ON knows.whom=whom.id
SPARQL: query relationships between objects.
WHERE { ?who foaf:knows ?whom .
?who foaf:name ?n1 .
?whom foaf:name ?n2 }
| subjects | predicates | object |
|---|---|---|
| order7 | product | product23 |
| order7 | shipDate | 20050508 |
| product23 | product-name | "Mystifier" |
| subjects | object |
|---|---|
| order7 | 20050508 |
| subjects | object |
|---|---|
| product23 | "Mystifier" |
Most of the data used in computer automation.
Use case: OrderTracking.
| id | customer | product | orderDate | shippingAddress |
|---|---|---|---|---|
| 2186 | 518 | 7385 | 2006-05-01 01:08:30 | NULL |
| 2186 | 208 | 2922 | 2006-05-01 18:34:38 | NULL |
| 2187 | 518 | 7439 | 2006-05-01 01:05:30 | NULL |
Term: Graph
Many ways to represent graphs:
<order prodct="#p23">...<Product id="p23" name="mystifier">
Both SPARQL and SQL can query graph data.
SQL graph shape comes from reuse of table aliases:
... FROM Orders AS o
WHERE o.orderDate < "20060501"
AND o.shipDate = "20060508"
SPARQL graph shape comes from reuse of variables.
PREFIX ot: <http://bigco.example/Orders/>
... WHERE { ?o ot:orderDate "20060501" .
?o ot:shipDate "20060508" }Term: restrict
SQL restricts cross joins on attribute values.
...
FROM Orders AS o
JOIN Products AS p ON o.product=p.id
SPARQL has links in the data model that it queries.
...
WHERE { ?o <Orders.products> ?p }
SELECT ?part ?descr ?given ?family ?posn ?rma ?billCity ?billState ?shipCity ?shipState
WHERE { { ?order <Orders.product> ?prod .
?order <Orders.customer> ?cust .
OPTIONAL { ?order <Orders.shippingAddress> ?shipAddr .
?shipAddr <Addresses.city> ?shipCity .
?shipAddr <Addresses.state> ?shipState }
} UNION {
?order <Returns.product> ?prod .
?order <Returns.customer> ?cust .
?order <Returns.rma> ?rma
}
?prod <Products.partNo> ?part .
?prod <Products.description> ?descr .
{ ?cust <Customers.id> ?num .
?cust <Customers.givenName> ?given .
?cust <Customers.familyName> ?family .
?cust <Customers.billingAddress> ?addr
} UNION {
?cust <Employees.id> ?num .
?cust <Employees.givenName> ?given .
?cust <Employees.familyName> ?family .
?cust <Employees.position> ?posn
}
?cust <Employees.homeAddress> ?addr .
?addr <Addresses.city> ?billCity .
?addr <Addresses.state> ?billState }
SELECT Products_0.partNo AS part,
Products_0.description AS descr,
U1.given,
U1.family,
U1.posn,U0.rma,
Addresses_1.city AS billCity,
Addresses_1.state AS billState,
U0.shipCity,
U0.shipState
FROM (
SELECT Orders_0.customer AS cust,
Orders_0.product AS prod,
NULL AS rma,
IF(Addresses_0.city IS NULL OR Addresses_0.state IS NULL, NULL, Addresses_0.city) AS shipCity,
IF(Addresses_0.city IS NULL OR Addresses_0.state IS NULL, NULL, Addresses_0.state) AS shipState
FROM Orders AS Orders_0
LEFT OUTER JOIN Addresses AS Addresses_0 ON Orders_0.shippingAddress=Addresses_0.id
WHERE Orders_0.customer IS NOT NULL AND Orders_0.product IS NOT NULL
UNION ALL
SELECT Returns_0.customer AS cust,
Returns_0.product AS prod,
Returns_0.RMAnumber AS rma,
NULL AS shipCity,
NULL AS shipState
FROM Returns AS Returns_0
WHERE Returns_0.customer IS NOT NULL AND Returns_0.product IS NOT NULL AND Returns_0.RMAnumber IS NOT NULL
) AS U0
INNER JOIN Products AS Products_0 ON U0.prod=Products_0.id
INNER JOIN (
SELECT Customers_0.id AS num,
Customers_0.givenName AS given,
Customers_0.familyName AS family,
NULL AS posn,
Customers_0.billingAddress AS addr
FROM Customers AS Customers_0
WHERE Customers_0.id IS NOT NULL AND Customers_0.givenName IS NOT NULL AND Customers_0.familyName IS NOT NULL AND Customers_0.billingAddress IS NOT NULL
UNION ALL
SELECT Employees_0.id AS num,
Employees_0.givenName AS given,
Employees_0.familyName AS family,
Employees_0.position AS posn,
Employees_0.homeAddress AS addr
FROM Employees AS Employees_0
WHERE Employees_0.id IS NOT NULL AND Employees_0.givenName IS NOT NULL AND Employees_0.familyName IS NOT NULL AND Employees_0.position IS NOT NULL AND Employees_0.homeAddress IS NOT NULL
) AS U1 ON U1.num=U0.cust
INNER JOIN Addresses AS Addresses_1 ON U1.addr=Addresses_1.id
WHERE Products_0.partNo IS NOT NULL AND Products_0.description IS NOT NULL AND Addresses_1.city IS NOT NULL AND Addresses_1.state IS NOT NULL;$query1 = "SELECT id FROM Orders WHERE Orders.shipDate = '20060501'"; mysql_query($query1); ... $query2 = "SPARQL: SELECT ?o WHERE { ?o <Orders.product> '20060501' }"; mysql_query($query2);
FROM (...) AS U0 INNER JOIN ( SELECT ... FROM Customers AS Customers_0 WHERE ... UNION ALL SELECT ... FROM Employees AS Employees_0 WHERE ... ) AS U1 ON U1.num=U0.cust
Term: tuple
Term: predicate
{ ?o <Orders.product> ?p }
{ ?o <Orders.product> ?p
?o <Orders.shipDate> ?ship }
{ ?t <Orders.product> ?p
OPTIONAL { ?t <Orders.shipDate> ?ship } }
SPARQL UNION corresponds to an SQL subselected UNION
WHERE { { ?x <TableA.field> ?y }
UNION
{ ?x <TableB.field> ?y } }
JOIN ( SELECT TableA.field AS foo FROM ... WHERE ...
UNION
SELECT TableB.field [AS foo] FROM ... WHERE ... ) AS U0 ON U0.foo=...
$#&@!!!
