0

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

测试表

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 列的数据...如何获得所需的输出?

4

2 回答 2

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其次,在没有计算特定值的日子里,这将不是空白。

于 2013-08-14T22:41:53.670 回答
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
于 2013-08-14T22:55:23.723 回答