簡體   English   中英

通過將行旋轉到動態列數來在MySQL中創建摘要視圖

[英]Create a Summary View in MySQL by pivoting row into dynamic number of columns

我在MySQL中有一個表,其中包含以下字段:

id, company_name, year, state

同一客戶和年份有多行,以下是數據示例:

    id | company_name  | year | state
----------------------------------------
    1  | companyA      | 2008 | 1
    2  | companyB      | 2009 | 2
    3  | companyC      | 2010 | 3
    4  | companyB      | 2009 | 1
    5  | companyC      | NULL | 3

我正在嘗試從此表創建一個視圖,以顯示每行一個公司(即GROUP BY pubco_name),其中狀態是給定年份的最高值。

以下是我要創建的視圖的示例:

    id | cuompany_name | NULL | 2008 | 2009 | 2010
--------------------------------------------------
    1  | companyA      | NULL | 1    | NULL | NULL
    2  | companyB      | NULL | 2    | NULL | NULL
    3  | companyC      | 3    | NULL | NULL | 3

有比這更多的數據,但你可以看到我想要實現的目標。

我不知道如何通過pubco_name為每年和組選擇最大狀態。 這是我到目前為止的SQL(我認為我們需要在這里使用CASE和/或sub-selects ):

SELECT
id,
company_name,
SUM(CASE WHEN year = 2008 THEN max(state) ELSE 0 END) AS 2008,
SUM(CASE WHEN year = 2009 THEN max(state) ELSE 0 END) AS 2009,
SUM(CASE WHEN year = 2010 THEN max(state) ELSE 0 END) AS 2010,
SUM(CASE WHEN year = 2011 THEN max(state) ELSE 0 END) AS 2011,
SUM(CASE WHEN year = 2012 THEN max(state) ELSE 0 END) AS 2012,
SUM(CASE WHEN year = 2013 THEN max(state) ELSE 0 END) AS 2013
FROM tbl
GROUP BY company_name
ORDER BY id DESC

感謝您的幫助,並提前致謝。

你需要轉動表,但mysql沒有任何這樣的pivot功能

所以我們需要復制它的功能

EDITED

Select 
  group_concat(
    DISTINCT 
       if(year is null,
          CONCAT('max(if (year is null, state, 0)) as ''NULL'' '),
          CONCAT('max(if (year=''', year, ''', state, 0)) as ''',year, ''' '))
    ) into @sql from tbl join (SELECT @sql:='')a;
set @sql = concat('select company_name, ', @sql, 'from tbl group by company_name;');
PREPARE stmt FROM @sql;
EXECUTE stmt;

結果

| COMPANY_NAME | 2008 | 2009 | 2010 | NULL |
--------------------------------------------
|     companyA |    1 |    0 |    0 |    0 |
|     companyB |    0 |    2 |    0 |    0 |
|     companyC |    0 |    0 |    3 |    3 |

SQL FIDDLE

有兩種方法可以解決您的問題1.為每年創建案例,這在您的情況下是不可能的,因為我們正在處理第2年。動態生成查詢以便我們根據您的需要獲得適當的列。

我根據第二個解決方案給出了解決方案,我將生成查詢並將其存儲在@sql變量中。 在小提琴中,我在執行它之前打印了@sql的內容。

select company_name, max(if (year='2008', state, 0)) as '2008' ,max(if (year='2009', state, 0)) as '2009' ,max(if (year='2010', state, 0)) as '2010' ,max(if (year is null, state, 0)) as 'NULL' from tbl group by company_name; 

有關group_concat()更多信息,請瀏覽GROUP_CONCATUSER DEFINED VARIABLE鏈接

希望這可以幫助..

請參閱此問題的答案中鏈接的頁面。

請注意,執行此操作時, 必須提前指定輸出中所需的列數。

在回答下面的注釋時,這里是一個簡單/基本的實現,它重現了上面的結果表(除了ID列;沒有意義,因為結果中的每一行都可以匯總輸入表中的多行)

SELECT
   `company_name`,
   NULLIF(SUM(CASE WHEN `t3`.`year` IS NULL THEN `t3`.`state` ELSE 0 END), 0) AS `null`,
   NULLIF(SUM(CASE WHEN `t3`.`year` = 2008 THEN `t3`.`state` ELSE 0 END), 0) AS `2008`,
   NULLIF(SUM(CASE WHEN `t3`.`year` = 2009 THEN `t3`.`state` ELSE 0 END), 0) AS `2009`,
   NULLIF(SUM(CASE WHEN `t3`.`year` = 2010 THEN `t3`.`state` ELSE 0 END), 0) AS `2010`
FROM
(
   SELECT
   `t1`.`id`,
   `t1`.`company_name`,
   `t1`.`year`,
   `t1`.`state`
   FROM `tbl` `t1`
   WHERE `t1`.`state` = (
      SELECT MAX(`state`)
      FROM `tbl` `t2`
      WHERE `t2`.`company_name` = `t1`.`company_name`
      AND (`t2`.`year` IS NULL AND `t1`.`year` IS NULL OR `t2`.`year` = `t1`.`year`)
   )
) `t3`
GROUP BY `t3`.`company_name`;

這使用嵌套查詢:內部查詢(使用t1t2別名)查找每年和公司具有最大狀態的行(除非您確定這是唯一的,否則將會中斷),以及外部查詢t3樞軸。

我會徹底測試這一點,以確保在真實數據上的性能是可接受的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM