MySQL查询帮助:如何透视这个表?

时间:2010-08-15 13:26:27

标签: sql database mysql

给出一个这样的表:

==============================================
| ID1 | ID2 | ID3 | Name          | Value    |
==============================================
| 16  | 1   | 100 | item_name     | Toys     |
| 16  | 2   | 101 | item_name     | Computer |
| 16  | 1   | 102 | item_price    | 55       |
| 16  | 2   | 103 | item_price    | 200      |
| 16  | 1   | 104 | animal_name   | dog      |
| 16  | 2   | 105 | animal_name   | cat      |
| 16  | 1   | 106 | animal_gender | male     |
| 16  | 2   | 107 | animal_gender | female   |
| 18  | 1   | 100 | item_name     | Toys     |
| 18  | 2   | 101 | item_name     | Computer |
| 18  | 1   | 102 | item_price    | 55       |
| 18  | 2   | 103 | item_price    | 200      |
| 18  | 1   | 104 | animal_name   | dog      |
| 18  | 2   | 105 | animal_name   | cat      |
| 18  | 1   | 106 | animal_gender | male     |
| 18  | 2   | 107 | animal_gender | female   |
----------------------------------------------

如何使用SQL来实现这样:

==============================================================
| ID1 | item_name | item_price | animal_name | animal_gender |
==============================================================
| 16  | Toys      | 55         | dog         | male          |
| 16  | Toys      | 55         | cat         | female        |
| 16  | Computer  | 200        | dog         | male          |
| 16  | Computer  | 200        | cat         | female        |
| 18  | Toys      | 55         | dog         | male          |
| 18  | Toys      | 55         | cat         | female        |
| 18  | Computer  | 200        | dog         | male          |
| 18  | Computer  | 200        | cat         | female        |
--------------------------------------------------------------

我将在PHP中创建SQL查询。

2 个答案:

答案 0 :(得分:1)

试试这个,对于MySQL(在ANSI SQL中不起作用):

SELECT  
  ID1,  
  GROUP_CONCAT(if(Name = 'item_name', Value, NULL)) AS 'item_name', 
  GROUP_CONCAT(if(Name = 'item_price', Value, NULL)) AS 'item_price', 
  GROUP_CONCAT(if(Name = 'animal_name', Value, NULL)) AS 'animal_name', 
  GROUP_CONCAT(if(Name = 'animal_name', Value, NULL)) AS 'animal_name', 
FROM tbl 
GROUP BY ID1, ID2, ID3;

(免责声明:未经测试您的数据。)

答案 1 :(得分:1)

编辑,遵循SONewbie的评论

应符合ANSI标准:

SELECT  
  ID1,  
  MAX(CASE WHEN Name = 'item_name' THEN Value ELSE NULL END) AS item_name, 
  MAX(CASE WHEN Name = 'item_price' THEN Value ELSE NULL END) AS item_price, 
  MAX(CASE WHEN Name = 'animal_name' THEN Value ELSE NULL END) AS animal_name, 
  MAX(CASE WHEN Name = 'animal_gender' THEN Value ELSE NULL END) AS animal_gender
FROM tbl 
GROUP BY ID1, ID2;

这不会产生所需的输出 - 相反,输出将如下所示:

==============================================================
| ID1 | item_name | item_price | animal_name | animal_gender |
==============================================================
| 16  | Toys      | 55         | dog         | male          |
| 18  | Toys      | 55         | dog         | male          |
| 16  | Computer  | 200        | cat         | female        |
| 18  | Computer  | 200        | cat         | female        |
--------------------------------------------------------------

这是因为ID1和ID2仅将猫和女性与计算机和200链接,而相同的字段仅将狗和男性与Toys和55链接。按ID3分组会引入大量NULL,因为ID1和ID3一起唯一地标识数据行。