国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

MySQL - 將行轉(zhuǎn)換為列
P粉538462187
P粉538462187 2023-10-13 11:50:31
0
1
771

我嘗試搜索帖子,但只找到了 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 |
   +--------+------+-----+-----+


P粉538462187
P粉538462187

全部回復(fù)(1)
P粉920199761

我將添加一個(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í),我使用三步過程來解決它(帶有可選的第四步):

  1. 選擇感興趣的列,即 y 值x 值
  2. 使用額外的列擴(kuò)展基表 - 每個(gè) x 值一列
  3. 對擴(kuò)展表進(jìn)行分組和聚合 - 每個(gè) y 值一組
  4. (可選)美化聚合表

讓我們將這些步驟應(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"",具體取決于您的具體情況
  • 分組時(shí)使用什么聚合函數(shù)。我使用了 sum,但是 countmax 也經(jīng)常使用(max 經(jīng)常在構(gòu)建單行時(shí)使用)分布在多行中的“對象”)
  • 使用多列表示 y 值。此解決方案不限于對 y 值使用單個(gè)列 - 只需將額外的列插入 group by 子句(并且不要忘記 select他們)

已知限制:

  • 此解決方案不允許數(shù)據(jù)透視表中有 n 列 - 在擴(kuò)展基表時(shí)需要手動添加每個(gè)數(shù)據(jù)透視列。因此,對于 5 或?? 10 個(gè) x 值,此解決方案很好。 100塊,不太好。有一些使用存儲過程生成查詢的解決方案,但它們很丑陋并且很難正確執(zhí)行。當(dāng)數(shù)據(jù)透視表需要有很多列時(shí),我目前不知道有什么好方法來解決這個(gè)問題。
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板