web-dev-qa-db-ja.com

SQLで垂直データを水平データに変換する方法は?

次のように、いくつかの関連アイテムを含むテーブル「アイテム」があります。

ID   Rel_ID  Name  RelRank
---  ------  ----  -------
1    1       foo   1
2    1       bar   2
3    1       zam   3
4    2       foo2  1

次のように、同じRel_IDのアイテムが同じ行に表示されるようにクエリを取得しようとしています。

Rel_ID  Name1  Name2  Name3
------  -----  -----  -----
1       foo    bar    zam
2       foo2

テーブルを複数回選択してみました:

SELECT k.Rel_ID, k.name 'Name1', k2.name 'Name2'
FROM item k, item k2
WHERE k.Rel_ID = k2.Rel_ID

しかし、これは失敗します。確かに、プロセスを大幅に簡略化できる変換やクエリはありますが、SQLをこの方法で以前に使用したことがないため、見逃しているだけです。何が欠けていますか?

[編集:データに表示されるRelRank列を追加]

18
Dan

使用しているデータベースに関係なく、達成しようとしていることの概念は「ピボットテーブル」と呼ばれます。

これがmysqlの例です。 http://en.wikibooks.org/wiki/MySQL/Pivot_table

一部のデータベースにはそのための組み込み機能があります。以下のリンクを参照してください。

SQLServer: http://msdn.Microsoft.com/de-de/library/ms177410.aspx

Oracle: http://www.dba-Oracle.com/t_pivot_examples.htm

ピボットはいつでも手動で作成できます。結果セットのすべての集計を選択し、その結果セットから選択するだけです。あなたの場合、rel_idに関連付けられている名前の数がわからないため、concatを使用してすべての名前を1つの列に入れることができます(mysqlではgroup_concatだと思います)。

あなたのケースの疑似選択(私はmysqlがわかりません):

select rel_id, group_concat(name) from item group by rel_id
20
Falcon

私はあなたがmysql固有の答えを探していると思います。構文はデータストアごとに異なる可能性があることに注意してください。

MySQLには、これを簡単にする機能があります。

SELECT Rel_ID, GROUP_CONCAT(Name SEPARATOR ' ') As Names FROM Item GROUP BY Rel_ID;

それはうまくいくはずです:-)

4
smartnut007

リストした名前が静的である場合、sqlfiddleで正常に実行した以下のクエリは機能します

SELECT rel_id,
MAX (DECODE (rel_id, '1', DECODE (relrank, '1', name) , '2',DECODE (relrank, '1', name))) NAME1,
MAX (DECODE (rel_id, '1', DECODE (relrank, '2', name))) NAME2,
MAX (DECODE (rel_id, '1', DECODE (relrank, '3', name))) NAME3
FROM supportContacts
GROUP BY rel_id

sQLフィドル

http://sqlfiddle.com/#!4/480e2/11

0
sayannayas