MySQL在数据透视表上选择非空列

时间:2014-11-25 16:44:21

标签: mysql sql pivot

我仍然有一些麻烦来理解透视表,但我设法做了这个工作查询:

select region,
sum(case when rescheduleCause = 'CLOSED' then round(reschedulePercentage,2) end) as 'CLOSED',
sum(case when rescheduleCause = 'RESHUFFLE' then round(reschedulePercentage,2) end) as 'RESHUFFLE',
sum(case when rescheduleCause = 'NEW PRIORITY' then round(reschedulePercentage,2) end) as 'NEW PRIORITY'

from fancy_table
group by region

我得到以下结果,计算结果是正确的:

region  | CLOSED | RESHUFFLE | NEW PRIORITY
___________________________________________
RegionA | 23.08  | NULL      | 38.46
RegiobB | 23.08  | NULL      | 7.69

我的问题在RESHUFFLE列中充满NULL个值。我想要的结果集如下所示:

region  | CLOSED | NEW PRIORITY
___________________________________________
RegionA | 23.08  | 38.46
RegiobB | 23.08  | 7.69

我知道如果我使用动态sql将此查询修改为存储过程可以实现这一点,但是我需要的列与这些列一样受限制,所以我认为它并不是真的那么必要。 我试过了:

    ifnull(sum(case when rescheduleCause = 'RESHUFFLE' then round(reschedulePercentage,2) end),0) as 'RESHUFFLE',
where `RESHUFFLE` is not null
where 'RESHUFFLE' is not null
having `RESHUFFLE` is not null

我没有想法,这肯定是一个简单的问题。有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

当您在SQL中查询时,您需要提前知道列数,而不能动态地排除列。如果您将拥有未知数量的列,那么您需要使用动态SQL来首先创建将要执行的sql字符串。

在MySQL中,这可以使用预准备语句来完成。这将首先查询您的表,仅返回您实际拥有的rescheduleCause值。这些值连接在一起成为一个sql字符串,然后您将使用此字符串创建要执行的最终查询:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(case when rescheduleCause = ''',
      rescheduleCause,
      ''' then round(reschedulePercentage,2) end) AS ',
      replace(rescheduleCause, ' ', '')
    )
  ) INTO @sql
from fancy_table;

SET @sql = CONCAT('SELECT region, ', @sql, ' 
                    from fancy_table
                    group by region');

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

请参阅SQL Fiddle with Demo