国が他の国から輸入する正味重量を表す行列の結果を返そうとしています。
Mysqlでピボットタイプのテーブルを生成するクエリを作成することができました。すべてのデータは単一のテーブルから取得されます。列(輸出国)を動的に作成し、その国で輸入された総正味重量で行を並べ替えることができました。
私が元に戻ろうとしているのは、列である輸出国を分類することです。簡単にアルファベット順に並べ替えることができますが、その列を動的に生成し、その列の合計で並べ替えるときに、何らかの方法で各列を合計する必要があります。
これは、myクエリの前のテーブルの例です。
REPORTER | PARTNER | NET_WEIGHT | YEAR | COMMODITY
--------------------------------------------------
Spain | USA | 3 | 2010 | wheat
Mexico | France | 5 | 2011 | wheat
Norway | USA | 2 | 2012 | wheat
Egypt | Canada | 5 | 2010 | wheat
Germany | UK | 1 | 2011 | wheat
Peru | France | 3 | 2011 | wheat
これが私が目指している構造の一例です。
REPORTER | TOTAL | USA | France | Canada | UK
------------------------------------------------------
TOTAL | | 5 | 4 | 3 | 3
------------------------------------------------------
Spain | 9 | 3 | 4 | 2 | NULL
Egypt | 6 | 2 | NULL | 1 | 3
Germany | 3 | 1 | NULL | NULL | NULL
これは私がこれまでに作成したクエリですが、上記のテーブルに似ていますが、正しくソートされていません。
SET @@group_concat_max_len = 500000;
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT CONCAT('GROUP_CONCAT(IF(`Partner` = ''', `Partner`,''', `NetWeight`, NULL)) AS ''',`Partner`,'''')
ORDER BY `Partner` ASC)
INTO @sql FROM `tblAnnualData`;
SET @sql = CONCAT('SELECT `Reporter`,SUM(`NetWeight`) AS Total,', @sql,' FROM `tblAnnualData`
WHERE `Commodity` = ''wheat''
AND `Year` = 2013
GROUP BY `Reporter`
ORDER BY `Total` DESC');
ステートメントでわかるように、「Partner」でアルファベット順に列を並べ替えることができますが、達成したいことは、net_weight列の合計を降順に並べ替えることです。したがって、テーブルを右および下に移動すると、最高値が左上に向かって減少します。
これはできますか? WITH ROLLUP
を使用した例を見てきましたが、何も動作しないようです。
私はあなたの例を編集し、WITH ROLLUP
、CASE
、およびFIELD
ステートメントを使用して、これをソートおよび作成しました。
mysql> SELECT * FROM test.tblAnnualData;
+----------+---------+------------+------+-----------+
| REPORTER | PARTNER | NET_WEIGHT | YEAR | COMMODITY |
+----------+---------+------------+------+-----------+
| Egypt | Canada | 5 | 2010 | wheat |
| Germany | UK | 1 | 2011 | wheat |
| Mexico | France | 5 | 2011 | wheat |
| Norway | USA | 2 | 2012 | wheat |
| Peru | France | 3 | 2011 | wheat |
| Spain | USA | 3 | 2010 | wheat |
+----------+---------+------------+------+-----------+
6 rows in set (0.00 sec)
SET @@group_concat_max_len = 500000;
SET @QUERY1 = NULL;
SELECT GROUP_CONCAT(DISTINCT CONCAT(" SUM(CASE WHEN PARTNER = '",PARTNER,"' THEN NET_WEIGHT ELSE 0 END) AS '",PARTNER,"'")
ORDER BY PARTNER ASC)
INTO @QUERY1
FROM tblAnnualData;
SET @QUERY1 = CONCAT("SELECT
REPORTER,
TOTAL,
USA,
France,
Canada,
UK
FROM (SELECT
IFNULL(REPORTER,'TOTAL') AS REPORTER,
SUM(NET_WEIGHT) AS TOTAL,",@QUERY1," FROM tblAnnualData
WHERE COMMODITY = 'wheat'
#AND Year = 2011
GROUP BY REPORTER WITH ROLLUP) AS A
ORDER BY FIELD(REPORTER,'TOTAL') DESC,
TOTAL DESC,
REPORTER ASC;");
PREPARE QUERY1 FROM @QUERY1;
EXECUTE QUERY1;
これは次のクエリと同じです。
SELECT
REPORTER,
TOTAL,
USA,
France,
Canada,
UK
FROM (SELECT
IFNULL(REPORTER,'TOTAL') AS REPORTER,
SUM(NET_WEIGHT) AS TOTAL,
SUM(CASE WHEN PARTNER='USA' THEN NET_WEIGHT ELSE 0 END) AS USA,
SUM(CASE WHEN PARTNER='France' THEN NET_WEIGHT ELSE 0 END) AS France,
SUM(CASE WHEN PARTNER='Canada' THEN NET_WEIGHT ELSE 0 END) AS Canada,
SUM(CASE WHEN PARTNER='UK' THEN NET_WEIGHT ELSE 0 END) AS UK
FROM tblAnnualData
GROUP BY REPORTER WITH ROLLUP) AS A
ORDER BY FIELD(REPORTER,'TOTAL') DESC,
TOTAL DESC,
REPORTER ASC;
FIELD
なのはなぜですか?
フィールドがFIELD
のときに最初にTOTAL
を使用して並べ替えました(つまり、WITH ROLLUP
によって生成された行のREPORTER
集計フィールド)。次に、 NET_WEIGHT
のTOTAL
。その後、いくつかのREPORTER
が他/他のREPORTER
と同じである場合に備えて、TOTAL
で終了します。
mysql> SET @@group_concat_max_len = 500000;
Query OK, 0 rows affected (0.00 sec)
mysql> SET @QUERY1 = NULL;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> SELECT GROUP_CONCAT(DISTINCT CONCAT(" SUM(CASE WHEN PARTNER = '",PARTNER,"' THEN NET_WEIGHT ELSE 0 END) AS '",PARTNER,"'")
-> ORDER BY PARTNER ASC)
-> INTO @QUERY1
-> FROM tblAnnualData;
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> SET @QUERY1 = CONCAT("SELECT
"> REPORTER,
"> TOTAL,
"> USA,
"> France,
"> Canada,
"> UK
"> FROM (SELECT
"> IFNULL(REPORTER,'TOTAL') AS REPORTER,
"> SUM(NET_WEIGHT) AS TOTAL,",@QUERY1," FROM tblAnnualData
"> WHERE COMMODITY = 'wheat'
"> #AND Year = 2011
"> GROUP BY REPORTER WITH ROLLUP) AS A
"> ORDER BY FIELD(REPORTER,'TOTAL') DESC,
"> TOTAL DESC,
"> REPORTER ASC;");
Query OK, 0 rows affected (0.00 sec)
mysql> PREPARE QUERY1 FROM @QUERY1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Statement prepared
mysql> EXECUTE QUERY1;
+----------+-------+------+--------+--------+------+
| REPORTER | TOTAL | USA | France | Canada | UK |
+----------+-------+------+--------+--------+------+
| TOTAL | 19 | 5 | 8 | 5 | 1 |
| Egypt | 5 | 0 | 0 | 5 | 0 |
| Mexico | 5 | 0 | 5 | 0 | 0 |
| Peru | 3 | 0 | 3 | 0 | 0 |
| Spain | 3 | 3 | 0 | 0 | 0 |
| Norway | 2 | 2 | 0 | 0 | 0 |
| Germany | 1 | 0 | 0 | 0 | 1 |
+----------+-------+------+--------+--------+------+
7 rows in set, 1 warning (0.00 sec)
mysql>
SQLFiddle で試してください