我嘗試搜索帖子,但只找到了 SQL Server/Access 的解決方案。我需要 MySQL (5.X) 中的解決方案。
我有一個(gè)包含 3 列的表(稱為歷史記錄):hostid、itemname、itemvalue。
如果我執(zhí)行選擇(select * from History
),它將返回
+--------+----------+-----------+ | hostid | itemname | itemvalue | +--------+----------+-----------+ | 1 | A | 10 | +--------+----------+-----------+ | 1 | B | 3 | +--------+----------+-----------+ | 2 | A | 9 | +--------+----------+-----------+ | 2 | C | 40 | +--------+----------+-----------+
如何查詢數(shù)據(jù)庫以返回類似內(nèi)容
+--------+------+-----+-----+ | hostid | A | B | C | +--------+------+-----+-----+ | 1 | 10 | 3 | 0 | +--------+------+-----+-----+ | 2 | 9 | 0 | 40 | +--------+------+-----+-----+
我將添加一個(gè)更長、更詳細(xì)的說明來說明解決此問題的步驟。如果太長,我深表歉意。
我將從您給出的基礎(chǔ)開始,并用它來定義幾個(gè)術(shù)語,我將在本文的其余部分使用這些術(shù)語。這將是基表:
select * from history; +--------+----------+-----------+ | hostid | itemname | itemvalue | +--------+----------+-----------+ | 1 | A | 10 | | 1 | B | 3 | | 2 | A | 9 | | 2 | C | 40 | +--------+----------+-----------+
這將是我們的目標(biāo),漂亮的數(shù)據(jù)透視表:
select * from history_itemvalue_pivot; +--------+------+------+------+ | hostid | A | B | C | +--------+------+------+------+ | 1 | 10 | 3 | 0 | | 2 | 9 | 0 | 40 | +--------+------+------+------+
history.hostid
列中的值將成為數(shù)據(jù)透視表中的y 值。 history.itemname
列中的值將變?yōu)?x-values(出于顯而易見的原因)。
當(dāng)我必須解決創(chuàng)建數(shù)據(jù)透視表的問題時(shí),我使用三步過程來解決它(帶有可選的第四步):
讓我們將這些步驟應(yīng)用于您的問題,看看會得到什么:
第 1 步:選擇感興趣的列。在所需的結(jié)果中,hostid
提供y 值,itemname
提供x 值。
第 2 步:使用額外列擴(kuò)展基表。我們通常需要每個(gè) x 值一列?;叵胍幌?,我們的 x 值列是 itemname
:
create view history_extended as ( select history.*, case when itemname = "A" then itemvalue end as A, case when itemname = "B" then itemvalue end as B, case when itemname = "C" then itemvalue end as C from history ); select * from history_extended; +--------+----------+-----------+------+------+------+ | hostid | itemname | itemvalue | A | B | C | +--------+----------+-----------+------+------+------+ | 1 | A | 10 | 10 | NULL | NULL | | 1 | B | 3 | NULL | 3 | NULL | | 2 | A | 9 | 9 | NULL | NULL | | 2 | C | 40 | NULL | NULL | 40 | +--------+----------+-----------+------+------+------+
請注意,我們沒有更改行數(shù) - 我們只是添加了額外的列。另請注意 NULL
的模式 - itemname = "A"
的行的新列 A
具有非空值,并且其他新列的空值。
第 3 步:對擴(kuò)展表進(jìn)行分組和聚合。我們需要按 hostid 分組
,因?yàn)樗峁┝?y 值:
create view history_itemvalue_pivot as ( select hostid, sum(A) as A, sum(B) as B, sum(C) as C from history_extended group by hostid ); select * from history_itemvalue_pivot; +--------+------+------+------+ | hostid | A | B | C | +--------+------+------+------+ | 1 | 10 | 3 | NULL | | 2 | 9 | NULL | 40 | +--------+------+------+------+
(請注意,我們現(xiàn)在每個(gè) y 值一行。) 好的,我們就快到了!我們只需要擺脫那些丑陋的 NULL
即可。
第四步:美化。我們將用零替換任何空值,以便結(jié)果集看起來更好:
create view history_itemvalue_pivot_pretty as ( select hostid, coalesce(A, 0) as A, coalesce(B, 0) as B, coalesce(C, 0) as C from history_itemvalue_pivot ); select * from history_itemvalue_pivot_pretty; +--------+------+------+------+ | hostid | A | B | C | +--------+------+------+------+ | 1 | 10 | 3 | 0 | | 2 | 9 | 0 | 40 | +--------+------+------+------+
我們就完成了——我們已經(jīng)使用 MySQL 構(gòu)建了一個(gè)漂亮的數(shù)據(jù)透視表。
應(yīng)用此過程時(shí)的注意事項(xiàng):
itemvalue
NULL
,但也可能是 0
或 ""
,具體取決于您的具體情況sum
,但是 count
和 max
也經(jīng)常使用(max
經(jīng)常在構(gòu)建單行時(shí)使用)分布在多行中的“對象”)group by
子句(并且不要忘記 select
他們)已知限制: