1. ホーム
  2. マイスル

[解決済み】MySQLでピボットテーブルの出力を返すには?

2022-04-28 03:28:58

質問

MySQLのテーブルが以下のようなものであった場合。

会社名 アクション ページ数
-------------------------------
A社 PRINT 3
A社 PRINT 2
A社 PRINT 3
B社 EMAIL   
B社 PRINT 2
B社 PRINT 2
B社PRINT1
A社 PRINT 3

MySQLのクエリを実行して、このような出力を得ることは可能でしょうか。

会社名 EMAIL PRINT 1 ページ PRINT 2 ページ PRINT 3 ページ
-------------------------------------------------------------
会社名A 0 0 1 3
B社 1 1 2 0

という考え方です。 pagecount が変化するため、出力カラムの量もそれを反映したものにする必要があります。 action / pagecount のペアを作成し、各ペアのヒット数 company_name . これはピボットテーブルと呼ばれるかどうかわかりませんが、誰かがそれを提案したのでしょうか?

どのように解決するのですか?

これは基本的に ピボット・テーブル

これを実現するための素敵なチュートリアルが、ここにあります。 http://www.artfulsoftware.com/infotree/qrytip.php?id=78

この投稿を読んで、この解決策をあなたのニーズに合わせて変更することをお勧めします。

更新情報

上記のリンクが現在利用できなくなってから、私はここでmysqlのピボットの答えを探しているすべてのあなたのためにいくつかの追加情報を提供する義務を感じています。しかし、私は、最初の場所で質問をしたpekuからの例で、一般的にSQLの方法でピボットテーブルを処理する方法についていくつかのアドバイスを与えるでしょう。

多分すぐにリンクが復活すると思うので、気をつけます。

表計算ソフトの方法で...

多くの人は、この目的のためにMSExcelやOpenOfficeなどのスプレッドシートツールを使っているだけです。これは有効な解決策で、データをそこにコピーし、GUIが提供するツールを使ってこれを解決します。

でも...これは質問と違うし、データをどうやってスプレッドシートに取り込むか、スケーリングの問題など、デメリットも出てくるかもしれませんね。

SQLの方法は...

彼のテーブルが次のようなものだとします。

CREATE TABLE `test_pivot` (
  `pid` bigint(20) NOT NULL AUTO_INCREMENT,
  `company_name` varchar(32) DEFAULT NULL,
  `action` varchar(16) DEFAULT NULL,
  `pagecount` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`pid`)
) ENGINE=MyISAM;

次に、目的のテーブルを調べます。

company_name    EMAIL   PRINT 1 pages   PRINT 2 pages   PRINT 3 pages
-------------------------------------------------------------
CompanyA        0       0               1               3
CompanyB        1       1               2               0

行( EMAIL , PRINT x pages ) が条件に似ている。主なグループ分けは company_name .

この条件を設定するためには、むしろ CASE -ステートメントを使用します。何かでグループ化するためには、まあ、使ってください ... GROUP BY .

このピボットを提供する基本的な SQL は、次のようなものになります。

SELECT  P.`company_name`,
    COUNT(
        CASE 
            WHEN P.`action`='EMAIL' 
            THEN 1 
            ELSE NULL 
        END
    ) AS 'EMAIL',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '1' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 1 pages',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '2' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 2 pages',
    COUNT(
        CASE 
            WHEN P.`action`='PRINT' AND P.`pagecount` = '3' 
            THEN P.`pagecount` 
            ELSE NULL 
        END
    ) AS 'PRINT 3 pages'
FROM    test_pivot P
GROUP BY P.`company_name`;

これで、目的の結果が非常に速く得られるはずです。この方法の主な欠点は、ピボット・テーブルの行数が増えるほど、SQL 文で定義する条件が増えることです。

これも、プリペアドステートメントやルーチン、カウンタなどを使って対処することが多いですね。

このトピックに関するいくつかの追加リンク。