1

假设我有一个名为“test”的表,其设计如下:

SELECT type, name, `key` FROM test
类型 | 姓名 | 钥匙
----------------------
  0 | 玛丽亚 | 123
  1 | 加布里埃尔 | 455
  0 | 蕾哈娜 | 69
  1 | 克里斯 | 7
  1 | 马丁 | 112

 

 

下一个查询允许我在一行中获取所有数据:

SELECT GROUP_CONCAT(type ORDER BY type) types, GROUP_CONCAT(name ORDER BY type) names, GROUP_CONCAT(`key` ORDER BY type) `keys` FROM test
  类型 | 姓名 | 钥匙
-------------------------------------------------- ----------------
0,0,1,1,1 | 蕾哈娜、玛丽亚、马丁、克里斯、加布里埃尔| 高分辨率照片| CLIPARTO 69,123,112,7,455

 

但这并不是我所需要的。如果我能够创建一个返回以下结果的查询,那就太完美了:

类型_0 | 姓名_0 | 键_0 | 类型_1 | 姓名_1 | 键_1
-------------------------------------------------- ----------------------------------
  0, 0 | 玛丽亚,蕾哈娜 | 123, 69 | 1, 1 | 加布里埃尔、克里斯、马丁| 高分辨率照片| CLIPARTO 455、7、112

 

有没有办法创建这样的查询?还是根本没有意义?

提前致谢。

4

2 回答 2

3

这是可能的,但我不会这样做。它看起来像这样:

SELECT * FROM 
(
  SELECT 
    GROUP_CONCAT(type ORDER BY type) types, 
    GROUP_CONCAT(name ORDER BY type) names, 
    GROUP_CONCAT(`key` ORDER BY type) `keys` 
  FROM test
  WHERE type = 0
) AS _type0,
(
  SELECT 
    GROUP_CONCAT(type ORDER BY type) types, 
    GROUP_CONCAT(name ORDER BY type) names, 
    GROUP_CONCAT(`key` ORDER BY type) `keys` 
  FROM test
  WHERE type = 1
) AS _type1;

如果找到更多类型,则无法动态生成更多列。这是数据透视表查询的典型特征——您必须在编写查询之前知道不同的值。

我会这样做:

SELECT 
  type,
  GROUP_CONCAT(name ORDER BY name) names, 
  GROUP_CONCAT(`key` ORDER BY name) `keys` 
FROM test
GROUP BY type;

输出应如下所示:

 type |         names        |  keys
------------------------------------------------------------------
 0    | maria,rihanna        | 123,69
 1    | chris,gabriel,martin | 7,455,112

编辑:name根据@GarethD 回答的建议,我在每个组中按顺序进行了此查询。

于 2013-11-19T00:29:11.817 回答
2

你可以这样做:

SELECT GROUP_CONCAT(CASE WHEN type = 0 THEN type END ORDER BY Type) AS types_0,
       GROUP_CONCAT(CASE WHEN type = 0 THEN name END ORDER BY Type) AS names_0,
       GROUP_CONCAT(CASE WHEN type = 0 THEN `key` END ORDER BY Type) AS keys_0,
       GROUP_CONCAT(CASE WHEN type = 1 THEN type END ORDER BY Type) AS types_1,
       GROUP_CONCAT(CASE WHEN type = 1 THEN name END ORDER BY Type) AS names_1,
       GROUP_CONCAT(CASE WHEN type = 1 THEN `key` END ORDER BY Type) AS keys_1
FROM   Test;

SQL Fiddle 示例

或者,如果您不知道可以动态生成 SQL 并使用准备好的语句的类型数量:

SET @SQL = '';

SELECT CONCAT('SELECT ',
                GROUP_CONCAT(DISTINCT
                    CONCAT('GROUP_CONCAT(CASE WHEN type = ', type, ' THEN type END ORDER BY Type) AS types_', type, ','
                            'GROUP_CONCAT(CASE WHEN type = ', type, ' THEN name END ORDER BY Type) AS names_', type, ','
                            'GROUP_CONCAT(CASE WHEN type = ', type, ' THEN `key` END ORDER BY Type) AS keys_', type
                    )), ' FROM Test;')
INTO    @SQL
FROM    Test;

PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQL-Fiddle 示例

然而,仅仅因为你可以做某事,并不意味着你应该这样做,而且我同意 Bill Karwin 的观点,显示这些数据的最明智的方式是按类型分组。此外,您的查询不是确定性的,您应该按类型以外的内容进行排序,以确保名称和键的顺序是一致的。

于 2013-11-19T00:37:47.020 回答