2013-03-19 168 views
2

我有两个表三倍和标签透视表使用MySQL

三同表有以下栏目

id PostID TagID Value 
    1 1  1  Murder 
    2 1  2  New Brunswick 
    3 2  1  Theft 
    4 2  3  Gun 

标签表有以下栏目

id TagName 
    1 Incident 
    2 Location 
    3 Weapon  

我试图写sql用动态头创建数据透视表

输出应该是这样的

 PostID Incident Location   Weapon   
      1 Murder  New Brunswick  
      2 Theft      Gun 

任何帮助编写SQL将不胜感激。我在网上看到的例子,但无法弄清楚这一个

+0

SQLFiddle(http://sqlfiddle.com)是检验思想的巨大资源。 – 2013-03-19 21:21:38

+0

可能重复的[MySQL数据透视列到动态列数](http://stackoverflow.com/questions/12004603/mysql-pivot-row-into-dynamic-number-of-columns) – RichardTheKiwi 2013-05-03 09:16:02

回答

11

为了在MySQL中的数据,您需要同时使用聚合函数和CASE表达。

如果你有一个已知的列数,那么你可以硬编码查询:

select p.postid, 
    max(case when t.tagname = 'Incident' then p.value end) Incident, 
    max(case when t.tagname = 'Location' then p.value end) Location, 
    max(case when t.tagname = 'Weapon' then p.value end) Weapon 
from triples p 
left join tags t 
    on p.tagid = t.id 
group by p.postid; 

SQL Fiddle with Demo

但是,如果你有一个未知的列数,那么你就需要使用准备好的语句生成动态SQL:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(CASE WHEN TagName = ''', 
     TagName, 
     ''' THEN p.value END) AS `', 
     TagName, '`' 
    ) 
) INTO @sql 
FROM tags; 


SET @sql 
    = CONCAT('SELECT p.postid, ', @sql, ' 
      from triples p 
      left join tags t 
      on p.tagid = t.id 
      group by p.postid'); 

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

请参阅SQL Fiddle with Demo

双方将给出结果:

| POSTID | INCIDENT |  LOCATION | WEAPON | 
---------------------------------------------- 
|  1 | Murder | New Brunswick | (null) | 
|  2 | Theft |  (null) | Gun | 
+0

非常感谢蓝色的脚 – Swakesh 2013-03-19 22:32:48