2015年3月5日木曜日

SPARQLで別グラフをLEFT JOIN, INNER JOINする

SPARQLでSQLみたいなJOINをしたいのです。

まずは、メインクエリとして、1つのグラフをSELECTするSPARQLを書きます。

SELECT *
FROM <graph1>
WHERE {
  ?s <商品コード> ?code
 .?s <商品名> ?name
}
LIMIT 3

商品コードと商品名がとれました。
[code],[name]
A01,にんじん
A02,じゃがいも
A03,ピーマン

次に、他のグラフをLEFT JOINしてみます。
JOINするグラフは、WHEREの中に、サブクエリとして書きます。
連結キーは ?code で、メインクエリとサブクエリで同じ名前にすることで、連結されます。

SELECT *
FROM <graph1>
WHERE {
  ?s <商品コード> ?code
 .?s <商品名> ?name
 .OPTIONAL{
   SELECT ?code ?price
   FROM <graph2>
   WHERE {
     ?s <商品コード> ?code
     .?s <お値段> ?price
   }
 }
}
LIMIT 3

他のグラフからお値段も取ってこれました。
[code],[name],[price]
A01,にんじん,100
A02,じゃがいも,50
A03,ピーマン,


続いて、LEFT JOINをINNER JOINに変えてみます。
サブクエリのOPTIONALを取るだけです。

SELECT *
FROM <graph1>
WHERE {
  ?s <商品コード> ?code
 .?s <商品名> ?name
 .{
   SELECT ?code ?price
   FROM <graph2>
   WHERE {
     ?s <商品コード> ?code
     .?s <お値段> ?price
   }
 }
}
LIMIT 3

こうすると、JOINした先のグラフに無いデータは出てきません。

[code],[name],[price]
A01,にんじん,100
A02,じゃがいも,50

このSPARQLはVirtuoso対応です。
サブクエリを複数書くことで、いくつでも連結できます。
他にも連結方法は有ると思いますが、この方法がわかりやすく、サブクエリ内でFILTERなどもできるので、活用しています。


ついでに、
連結キーが、トリプルでいうところの ?s ?p ?o の ?o で結びつけた例を紹介しましたが、
私が遭遇した、メインクエリの?oとサブクエリの?sで結び付けたい場合は、以下のように書きます。
サブクエリのSELECTの?sを文字列に変換し、別名として?codeを割り当てます。

SELECT *FROM <graph1>
WHERE {
  ?s <商品コード> ?code
 .?s <商品名> ?name
 .{
   SELECT (str(?s) AS ?code) ?price
   FROM <graph2>
   WHERE {
     ?s <お値段> ?price
   }
 }
}
LIMIT 3

これでうまく連結されました。
以上です!

0 件のコメント:

コメントを投稿