mysql - SQL if 查询功能
问题描述
我想编写一个查询来确定每种不同模式每天的成功率。我确实写了一个查询,该查询将按日期和模式分组,这符合我的目的,但我的一位前辈写了以下查询,它也有效,但我只是无法理解 if 子句是如何工作的。我将在这里添加一些查询 -
SELECT
dt,
sum(if(mode='A',success,0))AS a_s,
sum(if(mode='A',total,0))AS a_t,
sum(if(mode='B',success,0))AS b_s,
sum(if(mode='B',total,0))AS b_t,
sum(if(mode='C',success,0))AS c_s,
sum(if(mode='C',total,0))AS c_t,
sum(if(mode='D',success,0))AS d_s,
sum(if(mode='D',total,0))AS d_t,
sum(if(mode NOT in('A','B','C','D'),success,0))AS other_s,
sum(if(mode NOT in('A','B','C','D'),total,0))AS other_t
FROM
(SELECT
mode,
date(addedon)AS dt,
sum(if(status in('success','partial'),1,0))AS success,
count(*)AS total
FROM `a_huge_ass_table`
WHERE `studentid`=159633 AND addedon>'2021-01-15'
GROUP BY mode,date(addedon)
)AS t
在这里,我无法理解sum(if(mode='A',success,0))AS a_s,
- 这个 if 子句是如何工作的。如果条件为真,那么该子句返回成功?这项工作如何添加成功也以某种方式验证其状态是否为成功案例?我在谷歌上找不到这个。
解决方案
首先,if()
不是标准的SQL。我建议使用以下方法重写case
:
sum(case when mode = 'A' then success else 0 end) as a_s,
sum(case when mode = 'A' then total else 0 end) as a_t,
等等。
其次,这个查询缺少最后的group by dt
. dt
否则,它会为每个值生成一行,而不是单独的一行。
这称为条件聚合。最终结果集中的每一行都代表子查询中的一组行。在这个群体中,有些人有mode = 'A'
,有些人没有。对于具有mode = 'A'
上述总和的 和 的success
值total
。
顺便说一句,不需要子查询。这只会减慢查询速度。我建议将查询编写为:
SELECT date(addedon) as dt
SUM( mode = 'A' AND status IN ('success', 'partial') ) as a_success,
SUM( mode = 'A' ) as a_total,
. . .
FROM `a_huge_ass_table`
WHERE studentid = 159633 AND addedon >= '2021-01-15'
GROUP BY date(addedon);
请注意,这使用了 MySQL 扩展,其中布尔表达式被视为整数,“1”表示真,“0”表示假。
推荐阅读
- graphql - 空手道如何让 websocket 保持活力
- java - 如何从 citrus 测试类调用 citrus bean 配置类中的任何变量
- javascript - 是否可以通过css自动聚焦在div上?
- phpmyadmin - 如何将 vb.net 2012 连接到其他计算机上的数据库
- javascript - MongoDB如果字段不存在插入
- excel - 我在 Userform2 中创建了一个“返回”按钮来显示 Userform1,但出现错误:运行时错误 400 表单已经显示无法模态
- java - 更新recyclerview数据
- c++ - 从格式化输入操作中获取读取字符的数量
- docker - 如果 docker 更新它的 linux 内核,它会破坏现有的 docker 镜像吗?
- python - Python:百万条记录的缓慢处理