1対多で紐付くデータをArrayで返したい。(sqlite)

1つの本に対して複数のタグが付くようなデータベースを考えます。
Books(id, title), Book_Tag(book_id, tag_id), Tags(id, name)というようなテーブル構造になっていて(いわゆるToxi法)

Select
    Books.title,
    [tags] as tags  // tagの配列を返したい

というような形で取得したい時です。

結論からいうとsqliteで直接配列を扱うのは無理です。
ですが、GROUP_CONCATメソッドを使えばカンマ区切り文字列として取得できます。

SELECT 
  Books.title,
  GROUP_CONCAT(Tags.name) AS tags 
FROM Books
LEFT JOIN Books_Tags
  ON Books.id = Books_Tags
.book_id
LEFT JOIN Tags
  ON Books_Tags
.tag_id = Tags.id
GROUP BY Books.id

GROUP_CONCATというのはCountやAvgなどと同様にGroupByを行う時に利用できます。
グループ化される行をConcatつまり文字列連結してくれます。
連結文字は第2引数で指定しますが、省略した場合には’,’(カンマ)が使われます。

あとは取得後に配列に分解すればOKです。
なおPostgresの場合はARRAY_AGG関数というものがあるのでSQL側で配列の状態が扱えます。
羨ましいですね。

コメント