MySQL查询,透视表

时间:2015-04-15 14:11:20

标签: mysql pivot

我在构建查询时遇到问题,该查询将我的行转移到列。 我的Pivot是我的日期。用户需要的是查看整周的数据。

我的数据构造如下:

ID - AssemblyDate
----------------------------------
12345 - 2015-01-01
12346 - 2015-01-01
12347 - 2015-01-01
12348 - 2015-01-02
12349 - 2015-01-02
12350 - 2015-01-02
12351 - 2015-01-03
12352 - 2015-01-03
12353 - 2015-01-03

我期待的结果将是这样的

DAY1 - DAY2 - DAY3
12345  12348  12351
12346  12349  12352
12347  12350  12352

我的尝试:

SELECT CASE WHEN (AssemblyDate = '2015-01-01') THEN ID ELSE NULL END AS DAY1
       , CASE WHEN (AssemblyDate = '2015-01-02') THEN ID ELSE NULL END AS DAY2
       , CASE WHEN (AssemblyDate = '2015-01-03') THEN ID ELSE NULL END AS DAY3
FROM MyTable
GROUP BY AssemblyDate

这给了我这样的话:

DAY1 - DAY2 - DAY3
12345  NULL   NULL
12346  NULL   NULL
12347  NULL   NULL
NULL   12348  NULL
NULL   12349  NULL
NULL   12350  NULL
NULL   NULL   12351
NULL   NULL   12352
NULL   NULL   12352

但我不想要空值...有没有一种方法可以将它们归结为没有空值?

1 个答案:

答案 0 :(得分:1)

你需要做一些摆弄,因为你需要进一步分组这些结果。由于没有什么可以对它们进行分组,我们需要设计用于分组的东西 - 在这种情况下,每列一个变量,只要该列是与汇编日期匹配的那一列,我们就会递增:

select if(assemblydate = '2015-01-01', @d1c := @d1c +1, 
          if(assemblydate = '2015-01-02', @d2c := @d2c + 1, @d3c := @d3c +1)) id,  
       case when assemblydate = '2015-01-01' then id end d1,   
       case when assemblydate = '2015-01-02' then id end d2,   
       case when assemblydate = '2015-01-03' then id end d3  
  from d, (select @d1c := 0, @d2c := 0, @d3c := 0) q;

该查询只添加了一个id列,每天递增一次,结果如下所示。

+------+-------+-------+-------+
| id   | d1    | d2    | d3    |
+------+-------+-------+-------+
|    1 | 12345 |  NULL |  NULL |
|    2 | 12346 |  NULL |  NULL |
|    3 | 12347 |  NULL |  NULL |
|    1 |  NULL | 12348 |  NULL |
|    2 |  NULL | 12349 |  NULL |
|    3 |  NULL | 12350 |  NULL |
|    1 |  NULL |  NULL | 12351 |
|    2 |  NULL |  NULL | 12352 |
|    3 |  NULL |  NULL | 12352 |
+------+-------+-------+-------+

完成后,我们只围绕结果包装另一个查询,按ID分组,并使用max()

选取非空值
select max(d1), max(d2), max(d3) from
(
  select if(assemblydate = '2015-01-01', @d1c := @d1c +1, 
          if(assemblydate = '2015-01-02', @d2c := @d2c + 1, @d3c := @d3c +1)) id,  
       case when assemblydate = '2015-01-01' then id end d1,   
       case when assemblydate = '2015-01-02' then id end d2,   
       case when assemblydate = '2015-01-03' then id end d3  
  from d, (select @d1c := 0, @d2c := 0, @d3c := 0) q
) qq
group by id;

fiddle here