2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

SPARQLでSQLみたいなJOINをしたいのです。(これがSPARQLとして行うべきなのかどうかは別にして)

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

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

商品コードと商品名がとれました。

[code],[name]
A01,にんじん
A02,じゃがいも
A03,ピーマン


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

SPARQL
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を取るだけです。

SPARQL
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を割り当てます。

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

 .{
   SELECT (str(?s) AS ?code) ?price
   FROM <graph2>
   WHERE {
     ?s <お値段> ?price
   }
 }

}
LIMIT 3

これでうまく連結されました。
現場からは以上です!

(5年前の記事が下書きとして発見されたので投稿してみました。記事は完成していたのに、なぜ投稿してなかったのかは謎です。)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?