mysql如何将case语句作为列而不是行按日期分组

bksxznpy  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(366)

这个问题在这里已经有答案了

需要返回两组带有两个不同where子句的数据(2个答案)
两年前关门了。
不知道我问得对不对。我有一个查询,我试图根据另一个表的qty值显示每个原因id的总计,但在存在原因id的表中按月份分组。
到目前为止,我的问题是:

select
month(f.c_date),
case when q.reason_id = 2 then sum(f.produced) else 0 end as 'LowM',
case when q.reason_id = 3 then sum(f.produced) else 0 end as 'LowP',
case when q.reason_id = 4 then sum(f.produced) else 0 end as 'LowSC',

from freeze f
inner join freezeq q on f.id = q.frz_id
inner join location l on f.t_id = l.id

where 1=1
and f.c_date like '%2018%'
group by q.reason_id, month(f.c_date);

我需要删除“groupbyq.reason\uid”,但是当然总和值是不分开的。
我试图将案例显示为列和f.produced值的总和,但组在f.c\u日期。
我尝试了几种不同的子查询方式,但似乎无法得到它。
我很感激集体精神能给我的任何帮助!
谢谢!

fsi0uk1n

fsi0uk1n1#

我想你是在问如何做条件聚合。
将聚合移至条件外部。条件将返回要聚合的标量(如果满足条件)或返回0或null(如果不满足条件)。聚合函数将对返回的标量进行操作。
替换此项:

case when q.reason_id = 2 then sum(f.produced) else 0 end as 'LowM'

有了这个:

SUM( CASE WHEN q.reason_id = 2 THEN f.produced ELSE 0 END ) AS `LowM`

其他注意事项:
如果 c_date 是日期、日期时间或时间戳数据类型,
替换此条件:

f.c_date LIKE '%2018%'

f.c_date >= '2018-01-01'
AND f.c_date  < '2018-01-01' + INTERVAL 1 YEAR

这将使mysql能够在适当的索引上使用范围扫描操作(如果有适当的索引可用)
使用 LIKE 对日期进行比较将迫使mysql计算表中的每一行,转换每一行 c_date 值转换为字符串,并进行字符串比较。
(我们可能希望优化器足够“聪明”,能够找出更有效的重写,但它并没有那么聪明。)
这个 WHERE 1=1 对性能没有任何影响。我们经常在动态生成的where子句中看到这一点;应用程序代码只能附加 AND whatever ,而不是被一张支票弄得乱七八糟,看我们是否需要一张支票 WHERE 关键字代替 AND (对于where子句中的第一个条件。)
有没有新手被 WHERE 1=1 可以很容易地提高速度。

rekjcdws

rekjcdws2#

你好像想用条件聚合函数,用 case whensum 功能。

select
    month(f.c_date),
    sum(case when q.reason_id = 2 then f.produced) else 0 end) as 'LowM',
    sum(case when q.reason_id = 3 then f.produced else 0 end) as 'LowP',
    sum(case when q.reason_id = 4 then f.produced else 0 end) as 'LowSC'
from freeze f
inner join freezeq q on f.id = q.frz_id
inner join location l on f.t_id = l.id
where  f.c_date like '%2018%'
group by  month(f.c_date);

笔记
我移除 1=1 and 因为这在你的问题中没有意义。

相关问题