SQL生成所需的输出

时间:2013-07-18 03:20:38

标签: mysql sql pivot

来自以下数据(在MySQL数据库中):

mysql> select * from test;
+------------+--------+
| start      | name   |
+------------+--------+
| 2013-04-01 | Donald |
| 2013-04-02 | Daisy  |
| 2013-04-03 | Mickey |
| 2013-04-03 | Minnie |
| 2013-04-01 | Pluto  |
| 2013-04-02 | Goofy  |
+------------+--------+
6 rows in set (0.00 sec)

我想编写一个查询来生成看起来像的输出:

2013-04-01  2013-04-02  2013-04003
----------  ----------  ----------
Donald      Daisy       Mickey
Pluto       Goofy       Minnie

有人可以建议SQL查询来生成此输出吗?

如果它有用,这是我用来创建样本数据的代码。

create table test (
    start date,
    name varchar (20));

insert into test values ('2013-04-01','Donald');
insert into test values ('2013-04-02','Daisy');
insert into test values ('2013-04-03','Mickey');
insert into test values ('2013-04-03','Minnie');
insert into test values ('2013-04-01','Pluto');
insert into test values ('2013-04-02','Goofy');`

2 个答案:

答案 0 :(得分:1)

必须拥有数据透视表或一系列案例陈述。

Select 
      Case When Start = '2013-04-01' Then name End As '2013-04-01',
      Case When Start = '2013-04-02' Then name End As '2013-04-02',
      Case When Start = '2013-04-03' Then name End As '2013-04-03'
From Test;

如果表格更复杂,那么动态生成它会变得更加困难。通过简单地导出到Excel并使用数据透视表功能,可以更轻松地使用更大的数据。

答案 1 :(得分:1)

从给定的数据结构中,您无法获得所需的输出。因为记录之间没有任何关系(例如Id等)

如果我们这样使用GROUP_CONCAT()

Select 
      GROUP_CONCAT(Case When Start = '2013-04-01' 
                        Then name ELSE NULL End) As '2013-04-01',
      GROUP_CONCAT(Case When Start = '2013-04-02' 
                        Then name End) As '2013-04-02',
      GROUP_CONCAT(Case When Start = '2013-04-03' 
                        Then name End) As '2013-04-03'
From Test;

然后你会得到这样的输出:

|   2013-04-01 |  2013-04-02 |    2013-04-03 |
----------------------------------------------
| Donald,Pluto | Daisy,Goofy | Mickey,Minnie |

这是动态查询:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'GROUP_CONCAT(CASE WHEN Start = ''',
      `Start`,
      ''' THEN `name` ELSE NULL END) AS `',
      `Start`, '`'
    )
  ) INTO @sql
FROM Test;

SET @sql = CONCAT('SELECT ', @sql,'
                     FROM Test
                  ');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

请参阅this SQLFiddle

如果有类似ID的字段,您可以这样做:

Select ID,
      GROUP_CONCAT(Case When Start = '2013-04-01' 
                        Then name ELSE NULL End) As '2013-04-01',
      GROUP_CONCAT(Case When Start = '2013-04-02' 
                        Then name End) As '2013-04-02',
      GROUP_CONCAT(Case When Start = '2013-04-03' 
                        Then name End) As '2013-04-03'
From Test2
GROUP BY ID;

或像这样的动态查询:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'GROUP_CONCAT(CASE WHEN Start = ''',
      `Start`,
      ''' THEN `name` ELSE NULL END) AS `',
      `Start`, '`'
    )
  ) INTO @sql
FROM Test2;

SET @sql = CONCAT('SELECT ID, ', @sql,'
                     FROM Test2
                  GROUP BY ID
                  ');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

输出:

| ID | 2013-04-01 | 2013-04-02 | 2013-04-03 |
---------------------------------------------
|  1 |     Donald |      Daisy |     Mickey |
|  2 |      Pluto |      Goofy |     Minnie |

请参阅this SQLFiddle