多动态行转换成多列mysql

时间:2018-07-11 06:44:41

标签: mysql sql mysql-workbench

我正在使用mysql,我必须将多个重复的行分隔为列。表具有以下结构。

The table has following structure.

但是我需要这样。

enter image description here

注意:每个 DateTime 始终有6条记录。但是 Title Feedback 是动态的。我尝试使用

选择DateTime,

但这没有给出我的期望值。我写了一个代码(不考虑标题)

select 
    g.dateTime AS dateTime,
    g.feedback as feedback ,
    c.title AS title    
from gauge g
inner join category c on g.category_id=c.category_id AND c.title ='title' AND g.feedback ='feedback' 
group by g.dateTime

这是行不通的,我尝试了GROUP_CONCAT(.... SEPARATOR'.....' ),这给了我不期望的输出,只在一栏中给出了输出。我的方法可能是错误的。有人请帮我解决这个问题。预先感谢

3 个答案:

答案 0 :(得分:1)

使用动态数据透视表,因为存在许多不同的值

Fiddle to play with

string[]

答案 1 :(得分:0)

我只会使用条件聚合。在MySQL中,枚举值有些棘手(除非您使用的是MySQL 8 +):

select datetime,
       max(case when rn = 1 then title end) as title_1,
       max(case when rn = 1 then feedback end) as feedback_1,
       max(case when rn = 2 then title end) as title_2,
       max(case when rn = 2 then feedback end) as feedback_2,
       max(case when rn = 3 then title end) as title_3,
       max(case when rn = 3 then feedback end) as feedback_3,
       max(case when rn = 4 then title end) as title_4,
       max(case when rn = 4 then feedback end) as feedback_4,
       max(case when rn = 5 then title end) as title_5,
       max(case when rn = 5 then feedback end) as feedback_5,
       max(case when rn = 6 then title end) as title_6,
       max(case when rn = 6 then feedback end) as feedback_6
from (select gc.*,
             (@rn := if(@dt = g.dateTime, @rn + 1,
                        if(@dt := g.dateTime, 1, 1)
                       )
             ) as rn
      from (select g.dateTime, g.feedback, c.title AS title    
            from gauge g inner join
                 category c
                 on g.category_id = c.category_id and
                    c.title = 'title' and
                    g.feedback = 'feedback' 
            group by g.dateTime
            order by g.dateTime
           ) gc cross join
           (select @dt := '', @rn := 0) params
     ) gc
group by datetime;

我认为c.titleg.feedback上的过滤不正确。

答案 2 :(得分:-1)

这不是一种优化的方法,但是您可以将它们连接到表中,并根据行数乘以6进行过滤。这样,我们可以将6行分为6个不同的表

http://rextester.com/DLVV64095

SELECT MAIN.DateTime,
    TBL1.TITLE AS Title1,
    TBL1.FEEDBACK AS Feedback1,
    TBL2.TITLE AS Title2,
    TBL2.FEEDBACK AS Feedback2,
    TBL3.TITLE AS Title3,
    TBL3.FEEDBACK AS Feedback3,
    TBL4.TITLE AS Title4,
    TBL4.FEEDBACK AS Feedback4,
    TBL5.TITLE AS Title5,
    TBL5.FEEDBACK AS Feedback5,
    TBL6.TITLE AS Title6,
    TBL6.FEEDBACK AS Feedback6
FROM (
    SELECT [DATETIME] AS [DateTime]
    FROM GAUGE
    GROUP BY [DATETIME]
) MAIN
INNER JOIN (
    SELECT G.DATETIME,
        G.FEEDBACK,
        C.TITLE,
        ROW_NUMBER() OVER(PARTITION BY ORDER BY (SELECT 1) ASC) AS ROWNO
    FROM GAUGE G
    INNER JOIN CATEGORY C
        ON G.CATEGORY_ID = C.CATEGORY_ID
) TBL1
    ON TBL1.DATETIME = MAIN.[DateTime]
    AND TBL1.ROWNO % 6 = 1
INNER JOIN (
    SELECT G.DATETIME,
        G.FEEDBACK,
        C.TITLE,
        ROW_NUMBER() OVER(PARTITION BY ORDER BY (SELECT 1) ASC) AS ROWNO
    FROM GAUGE G
    INNER JOIN CATEGORY C
        ON G.CATEGORY_ID = C.CATEGORY_ID
) TBL2
    ON TBL2.DATETIME = MAIN.[DateTime]
    AND TBL2.ROWNO % 6 = 2
INNER JOIN (
    SELECT G.DATETIME,
        G.FEEDBACK,
        C.TITLE,
        ROW_NUMBER() OVER(PARTITION BY ORDER BY (SELECT 1) ASC) AS ROWNO
    FROM GAUGE G
    INNER JOIN CATEGORY C
        ON G.CATEGORY_ID = C.CATEGORY_ID
) TBL3
    ON TBL3.DATETIME = MAIN.[DateTime]
    AND TBL3.ROWNO % 6 = 3
INNER JOIN (
    SELECT G.DATETIME,
        G.FEEDBACK,
        C.TITLE,
        ROW_NUMBER() OVER(PARTITION BY ORDER BY (SELECT 1) ASC) AS ROWNO
    FROM GAUGE G
    INNER JOIN CATEGORY C
        ON G.CATEGORY_ID = C.CATEGORY_ID
) TBL4
    ON TBL4.DATETIME = MAIN.[DateTime]
    AND TBL4.ROWNO % 6 = 4
INNER JOIN (
    SELECT G.DATETIME,
        G.FEEDBACK,
        C.TITLE,
        ROW_NUMBER() OVER(PARTITION BY ORDER BY (SELECT 1) ASC) AS ROWNO
    FROM GAUGE G
    INNER JOIN CATEGORY C
        ON G.CATEGORY_ID = C.CATEGORY_ID
) TBL5
    ON TBL5.DATETIME = MAIN.[DateTime]
    AND TBL5.ROWNO % 6 = 5
INNER JOIN (
    SELECT G.DATETIME,
        G.FEEDBACK,
        C.TITLE,
        ROW_NUMBER() OVER(PARTITION BY ORDER BY (SELECT 1) ASC) AS ROWNO
    FROM GAUGE G
    INNER JOIN CATEGORY C
        ON G.CATEGORY_ID = C.CATEGORY_ID
) TBL6
    ON TBL6.DATETIME = MAIN.[DateTime]
    AND TBL6.ROWNO % 6 = 0