質問: SQLについて質問です。 ※postgresで実行します。
回答: PostgreSQL 9.0以降なら「STRING_AGG」関数が使えます。 メリットとしては配列→配列の集約という段階を一つで集約可能なこと、集約する項目の並び順を指定できることです。 SELECT ID,STRING_AGG(フルーツ,',' ORDER BY フルーツ) FROM TBL WHERE ID IN (SELECT ID FROM TBL WHERE フルーツ='リンゴ') AND ID NOT IN (SELECT ID FROM TBL WHERE フルーツ='メロン') GROUP BY ID; のようになります。(ID順にまとめたい時はORDER BY ID) あと、IDについて特定のフルーツのありなしについては「IN、NOT IN」だけでなく、「EXISTS、NOT EXITS」も使えます。 SELECT ID,STRING_AGG(フルーツ,',' ORDER BY フルーツ) FROM TBL T1 WHERE EXISTS ( SELECT 1 FROM TBL T2 WHERE T2.ID=T1.ID AND T2.フルーツ='リンゴ') AND NOTT EXISTS ( SELECT 1 FROM TBL T3 WHERE T2.ID=T1.ID AND T3.フルーツ='メロン') GROUP BY ID; パフォーマンス的にはインデックスの有無などにもよるのでどちらが優れているかは一概に言えません。PostgreSQLはIN条件でセミハッシュ結合、アンチセミハッシュ結合が使えるので。 ARRAY_AGGは8.4以降で使えますがそれを含めてNOT INを使う場合に気をつけなればならないのはNULLについてです。 今回はないかもしれませんが NULL | メロン というデータがあるとSQLが返すのは0行です。 こうしたことはNOT EXISTSでは発生しません。 その点は留意してください。