MYSQL计数条目和按两个条件分组,输出到2d表

时间:2013-08-14 22:38:01

标签: mysql count group-by

我有一张看起来像这样的桌子; (实际表格较大,有几百万行)

TEST_TABLE

ID  Day Value
=============
1   1   4
2   1   -1
3   1   27
4   1   3
5   1   -2
6   1   -5
7   1   3
8   1   1
9   1   1
10  1   Null
11  2   1
12  2   1
13  2   2
14  2   -1
15  2   -3

我希望生成这两列的表,其中包含每个条目出现次数的计数,带有行的日期的2d表,以及顶部的值,每个单元格包含条目的数量这个标准如下;

期望的输出

Day    Null -5  -3  -2  -1  1   2   3   4   27
==================================================================================
1      1     1       1   1  2       2   1   1
2                1       1  2   1           

像;

这样的查询
select day, value, count(*) as count 
    from test_Table 
    group by day, value 
    Order by day asc,  value desc
;

生成数据的行数只有3列......如何获得所需的输出?

2 个答案:

答案 0 :(得分:1)

您可以使用条件聚合执行此操作:

select day,
       sum(value is NULL) as "NULL",
       sum(value = -5) as "-5",
       sum(value = -3) as "-3",
       sum(value = -2) as "-2",
       sum(value = -1) as "-1",
       sum(value = 1) as "1",
       sum(value = 2) as "2",
       sum(value = 3) as "3",
       sum(value = 4) as "4",
       sum(value = 27) as "27"
from test_Table 
group by day
Order by day asc;

注意两件事。首先,列值是固定的。如果需要动态列名,则需要使用动态SQL。其次,对于没有计算特定值的日期,这将是0而不是空白。

答案 1 :(得分:1)

简短的回答是它无法在MySQL中完成。

原因是SELECT语句必须指定要返回的列数,每列的名称和数据类型。并且MySQL无法动态生成要为您返回的列。

答案越长,您需要查询表单:

SELECT t.Day
     , SUM(IF(t.value IS NULL,1,0)) AS `Null`
     , SUM(IF(t.value = -5   ,1,0)  AS `-5`
     , SUM(IF(t.value = -3   ,1,0)  AS `-3`
     , ...
  FROM mytable t
GROUP BY t.Day

在SELECT列表中指定每个列。

您可以使用的一个技巧是使用另一个单独的查询来帮助编写您需要的查询。这必须是一个单独的步骤,一个单独的查询。要获取要作为列标题返回的值列表,请使用以下格式:

SELECT IFNULL(v.value,'Null') AS val
  FROM mytable v
 GROUP BY v.value
 ORDER BY IF(v.value IS NULL,0,1), v.value

如果你只是在MySQL(而不是应用程序)中这样做,你可以让MySQL帮助为你生成所需的SQL文本(使用SQL生成SQL)

SELECT CONCAT('     , SUM(IF(t.value',
         IFNULL(v.value,' IS NULL',CONCAT(' = ',v.value)),
         ',1,0)) AS `',v.value,'`'
       ) AS expr
  FROM mytable v
 GROUP BY v.value
 ORDER BY IF(v.value IS NULL,0,1), v.value

然后复制从expr列返回的字符串值,将它们粘贴到编辑器中,然后完成创建SQL语句,如上例所示。


Gordon的回答显示IF(col=12,1,0)表达式可以缩写为col=12

我总是发现自己在IF(conditional,valtrue,valfalse)打字,但那就是我大脑的工作方式。这对我来说更容易阅读。

同样,我的例子中的ORDER BY中的表达式......

ORDER BY IF(v.value IS NULL,0,1) 

可以改写......

ORDER BY v.value IS NOT NULL