使用group加入mysql on self

时间:2012-08-14 05:33:59

标签: mysql pivot

 id | name | year

数据:

 1  | ham   | 2006
 2  | ham   | 2007
 3  | ham   | 2008
 4  | amm   | 2007
 5  | amm   | 2008
 6  | inn   | 2009

现在我正在尝试构建一个sql,它给我以下输出(或类似的)

 name  | y1   | y2   | y3   | y4    
 ham   | 2006 | 2007 | 2008 | null
 amm   | null | 2007 | 2008 | null
 inn   | null | null | null | 2009

当进行多个(自我)左连接时,我得到了这个,但是只有为该名称设置了2006。有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:5)

你想要的是所谓的“支点”,你需要的是一个有条件的sum

select
   name,
   sum(year = 2006) as y1,
   sum(year = 2007) as y2,
   sum(year = 2008) as y3,
   sum(year = 2009) as y4
from mytable
group by name;

没有加入,没有muss,没有大惊小怪。它会表现得非常好。

这是有效的,因为在mysql中,true1false0,所以总结一个条件会计算它的真实次数!

请注意,对于“无数据”年份,这将为您提供零而不是null s,这可能更好。如果你真的想要空值,请使用if(sum(year = 2006) = 0, null, sum(year = 2006)) as y1等,但希望你不需要它。

答案 1 :(得分:1)

这是给出你的例子(sqlfiddle)的一种方式:

SELECT t1.name, MAX(y1.year) AS y1, MAX(y2.year) AS y2, MAX(y3.year) AS y3, MAX(y4.year) AS y4
FROM theTable t1
LEFT OUTER JOIN theTable y1 ON t1.name = y1.name AND y1.year = 2006
LEFT OUTER JOIN theTable y2 ON t1.name = y2.name AND y2.year = 2007
LEFT OUTER JOIN theTable y3 ON t1.name = y3.name AND y3.year = 2008
LEFT OUTER JOIN theTable y4 ON t1.name = y4.name AND y4.year = 2009
GROUP BY t1.name

答案 2 :(得分:0)

如果您不介意结果的结构,可以使用group_concat

select name , group_concat(ifnull(year ,'null') separator ', ') 
              as years from table 

将结果显示为:

name  | years
ham   | 2006 , 2007 , 2008 , null
amm   | null , 2007 , 2008 , null
inn   | null , null , null , 2009