MySQL:使用IF语句进行数据透视,但获取大量NULL值

时间:2012-12-11 15:42:02

标签: mysql pivot pivot-table

我有一些由五分标签组织的数据(-1,1,2,3,4,5)。对于Quintile列中的每个值,在另一列中都有一个名为ret的值。最后,有一列日期包含月末日期为整数。

我的目标是同时可视化所有Quintile返回数据,每个数据都是自己的列,只有日期列就像索引一样。

基本上,我想转向Quintile列,我看到其他地方建议在MySQL中使用IF语句作为实现此目的的方法。

例如,这是一个显示一个Quintile价值数据的查询:

select yearmonth, ret
where Quintile=1
from quintile_returns

但是我不想为所有Quintile标签重复这一点,单独保存数据,并在Python Pandas或Excel中将它们拼凑在一起。我想让SQL将其显示为不同的列。

但是当我尝试这个IF语句风格穷人的支点时,这就是我使用的查询:

select yearmonth, 
       IF(Quintile=1, ret, NULL) as Q1_ret,
       IF(Quintile=2, ret, NULL) as Q2_ret
from quintile_returns

我基本上得到了有效数据的对角线。 Quintile不是1的所有行仍然显示,填充为NULL,然后依次为Quintile 2。

如何避免所有这些额外的NULL值?基本上,我想告诉SQL如果条件满足则返回列的值 ,并且不要使用NULL或其他任何东西作为默认的else - 就像占位符一样。

有没有办法不涉及嵌套的连接类型语句?

2 个答案:

答案 0 :(得分:2)

由于您希望只有一行输出用于多行输入数据,因此您必须聚合您的值。在这种情况下,您希望按yearmonth对它们进行分组。一种可能的(虽然不是特别便携)方式如下:

SELECT yearmonth
     , SUM((Quintile=1)*ret) AS Q1
     , SUM((Quintile=2)*ret) AS Q2
FROM quintile_returns
GROUP BY yearmonth

这种稍微有些hackish的方法利用了这样一个事实,即MySQL中的Quintile=1之类的比较产生一个整数,0表示假,1表示真。因此,您将1*ret=ret用于匹配的Quintile,将0*ret=0用于其他Quintile。如果您希望事情更清晰,更便携,您也可以将其写为

SELECT yearmonth
     , SUM(IF(Quintile=1, ret, 0)) AS Q1
     , SUM(IF(Quintile=2, ret, 0)) AS Q2
FROM quintile_returns
GROUP BY yearmonth

答案 1 :(得分:1)

您可以使用GROUP BY仅为每个yearmonth值显示一行,然后使用SUM()以及IF()语句,以便ret VALUES仅在列的IF()条件的计算结果为TRUE:

SELECT `yearmonth`,
    SUM(IF(`Quintile` = 1, ret, NULL)) as `Q1_ret`,
    SUM(IF(`Quintile` = 2, ret, NULL)) as `Q2_ret`
FROM `quintile_returns`
GROUP BY `yearmonth`

否则,您对IF()语句有正确的想法。