web-dev-qa-db-ja.com

Mysql、データを長い/高いから広いに再形成します

Mysqlテーブルにlong/tall形式(以下で説明)のデータがあり、それをワイド形式に変換したいと思います。 SQLだけを使用してこれを行うことはできますか?

例を挙げて説明するのが最も簡単です。 Mか国、N個のキー(たとえば、キーは収入、政治指導者、地域、大陸など)の(国、キー、値)に関する情報があるとします。

Long format has 3 columns: country, key, value
  - M*N rows.
  e.g. 
  'USA', 'President', 'Obama'
   ...
  'USA', 'Currency', 'Dollar'

Wide format has N=16 columns: county, key1, ..., keyN
  - M rows
example: 
   country, President, ... , Currency
   'USA', 'Obama', ... , 'Dollar'

ワイドフォーマットのデータで新しいテーブルを作成する方法はSQLにありますか?

select distinct key from table;

//これですべてのキーが取得されます。

1)次に、これらの重要な要素を使用してテーブルを作成するにはどうすればよいですか?

2)次に、テーブルの値を入力するにはどうすればよいですか?

私はこれを任意のスクリプト言語(私はPythonが好きです)で実行できると確信していますが、mysqlでこれを実行する簡単な方法があるかどうかを知りたいと思いました。 RやSTATAなどの多くの統計パッケージには、頻繁に使用されるため、このコマンドが組み込まれています。

======

より明確にするために、単純なケースで必要な入出力を次に示します。

入力:

country    attrName    attrValue     key  (these are column names)
US         President   Obama         2
US         Currency    Dollar        3
China      President   Hu            4
China      Currency    Yuan          5

出力

country    President    Currency    newPkey
US         Obama        Dollar      1
China      Hu           Yuan        2
25
chongman

クロス集計またはピボットテーブルがその答えです。そこから、SELECT FROM ... INSERT INTO ...を実行するか、単一のSELECTからVIEWを作成できます。

何かのようなもの:

SELECT country, 
       MAX( IF( key='President', value, NULL ) ) AS President,
       MAX( IF( key='Currency', value, NULL ) ) AS Currency,
       ...

FROM table 
GROUP BY country;

詳細情報: http://dev.mysql.com/tech-resources/articles/wizard/index.html

20
mluebke

VIEWSとINSERTINTOを使用するソリューションを見つけたと思います(e4c5で提案されています)。

AttrNames/Keysのリストを自分で取得する必要がありますが、MYSQLは他の面倒な作業を行います。

上記の単純なテストケースでは、適切な列を使用してnew_tableを作成します(自動インクリメントの主キーも忘れないでください)。次に

CREATE VIEW a
AS SELECT country, attrValue
WHERE attrName="President";

CREATE VIEW b
AS SELECT country, attrValue
WHERE attrName="Currency";


INSERT INTO newtable(country, President, Currency)
SELECT a.country, a.attrValue, b.attrValue
FROM  a
INNER JOIN b  ON a.country=b.country;

より多くのattrNameがある場合は、ビューごとに1つのビューを作成し、それに応じて最後のステートメントを調整します。

INSERT INTO newtable(country, President, Currency, Capital, Population)
SELECT a.country, a.attrValue, b.attrValue, c.attrValue, d.attrValue
FROM  a
INNER JOIN b  ON a.country=b.country
INNER JOIN c  ON a.country=c.country
INNER JOIN d  ON a.country=d.country;

その他のヒント

  • nATURAL LEFT JOINを使用すると、ON句を指定する必要はありません。
5
chongman

SQL Serverを使用している場合、これは [〜#〜] unpivot [〜#〜] を使用すると簡単です。私の知る限り、これはMySQLに実装されていないので、これを実行したい場合(そして、それをお勧めします)、SQLを動的に生成する必要があり、それは面倒です。

3
Mark Byers