MySQL 如何使用 CASE 语句作为列而不是行按日期分组
MySQL How to group by date with CASE statements as columns instead of rows
不确定我问的是否正确。
我有一个查询,我试图根据另一个 table 数量值显示每个 reason_id 的总计,然后在 reason_id 存在的 table 中按月分组.
到目前为止我的查询是:
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);
我需要删除 "group by q.reason_id" 但当然 SUM 值不会分开。
我正在尝试将 CASE 显示为列和 f.produced 值的 SUM,但在 f.c_date.
上分组
我尝试了几种不同的子查询方法,但似乎无法理解。
感谢集体思想能给我的任何帮助!
谢谢!
您似乎想使用条件聚合函数,在sum
函数中使用case when
。
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
,因为您的查询中没有任何意义。
我想你问的是如何进行条件聚合。
将聚合移动到条件之外。条件将 return 我们要聚合的标量(如果满足条件)或 return 0 或 NULL(如果不满足条件)。聚合函数将在 returned 标量上运行。
替换为:
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
是 DATE、DATETIME 或 TIMESTAMP 数据类型,
替换此条件:
f.c_date LIKE '%2018%'
和
f.c_date >= '2018-01-01'
AND f.c_date < '2018-01-01' + INTERVAL 1 YEAR
这将使 MySQL 在 suitable 索引上使用范围扫描操作(如果 suitable 索引可用。)
在 DATE 上使用 LIKE
比较将强制 MySQL 评估 table 中的 每个 行,以转换每个 c_date
将值转换成字符串,并进行字符串比较。
(我们可能希望优化器 "smart" 足以找出更有效的重写,但它并不是那么聪明。)
WHERE 1=1
对性能没有任何影响。我们经常在动态生成的 WHERE 子句中看到这一点;应用程序代码可以只附加 AND whatever
,而不是检查我们是否需要 WHERE
关键字来代替 AND
(对于 WHERE 子句中的第一个条件) .)
任何被 WHERE 1=1
搞糊涂的新手都可以很容易地上手。
不确定我问的是否正确。 我有一个查询,我试图根据另一个 table 数量值显示每个 reason_id 的总计,然后在 reason_id 存在的 table 中按月分组.
到目前为止我的查询是:
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);
我需要删除 "group by q.reason_id" 但当然 SUM 值不会分开。
我正在尝试将 CASE 显示为列和 f.produced 值的 SUM,但在 f.c_date.
上分组我尝试了几种不同的子查询方法,但似乎无法理解。
感谢集体思想能给我的任何帮助!
谢谢!
您似乎想使用条件聚合函数,在sum
函数中使用case when
。
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
,因为您的查询中没有任何意义。
我想你问的是如何进行条件聚合。
将聚合移动到条件之外。条件将 return 我们要聚合的标量(如果满足条件)或 return 0 或 NULL(如果不满足条件)。聚合函数将在 returned 标量上运行。
替换为:
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
是 DATE、DATETIME 或 TIMESTAMP 数据类型,
替换此条件:
f.c_date LIKE '%2018%'
和
f.c_date >= '2018-01-01'
AND f.c_date < '2018-01-01' + INTERVAL 1 YEAR
这将使 MySQL 在 suitable 索引上使用范围扫描操作(如果 suitable 索引可用。)
在 DATE 上使用 LIKE
比较将强制 MySQL 评估 table 中的 每个 行,以转换每个 c_date
将值转换成字符串,并进行字符串比较。
(我们可能希望优化器 "smart" 足以找出更有效的重写,但它并不是那么聪明。)
WHERE 1=1
对性能没有任何影响。我们经常在动态生成的 WHERE 子句中看到这一点;应用程序代码可以只附加 AND whatever
,而不是检查我们是否需要 WHERE
关键字来代替 AND
(对于 WHERE 子句中的第一个条件) .)
任何被 WHERE 1=1
搞糊涂的新手都可以很容易地上手。