首页 > 解决方案 > 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 子句是如何工作的。如果条件为真,那么该子句返回成功?这项工作如何添加成功也以某种方式验证其状态是否为成功案例?我在谷歌上找不到这个。

标签: mysqlsql

解决方案


首先,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'上述总和的 和 的successtotal

顺便说一句,不需要子查询。这只会减慢查询速度。我建议将查询编写为:

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”表示假。


推荐阅读