【问题标题】:Selecting multiple columns from two tables in which one column of a table has multiple where conditions and group them by two columns and order by one从两个表中选择多个列,其中一个表的一列具有多个 where 条件,并将它们按两列分组并按一排序
【发布时间】:2019-05-21 06:12:54
【问题描述】:

我有两个表,分别是“appointment”和“skills_data”。

约会表的结构是:

id_ap || ap_meet_date || id_skill || ap_status. 

而ap_status的值有complete、confirm、cancel和miss。

而技能数据表包含两列,即:

id_skill || skill

我想获取每个条件的约会总数

ap_status = ('complete' and 'confirm'), 
ap_status = 'cancel' and 
ap_status = 'missed' 

GROUP BY id_skill and year and 
order by year DESC

我尝试了这个查询,它只计算了一个条件,但我想根据前面提到的 group by 和 order by 子句获得另外两个条件。

如果没有符合特定条件的记录(例如:某项技能2018年缺约0次),则应显示输出值为0表示零计数。

有人可以向我建议我是否应该实施多选查询或 CASE 子句来实现我的预期结果。我在约会表中有很多记录,并且想要一种有效的方式来查询我的记录。谢谢!

SELECT a.id_skill, YEAR(a.ap_meet_date) As year, s.skill,COUNT(*) as count_comp_conf 
FROM appointment a,skills_data s WHERE a.id_skill=s.id_skill and a.ap_status IN ('complete', 'confirm') 
GROUP BY `id_skill`, `year` 
ORDER BY `YEAR` DESC

我的查询的输出:

 id_skill | year | skill | count_comp_conf 
 -----------------------------------------
 1          2018     A          20        
 2          2018     B          15        
 1          2019     A          10         
 2          2019     B          12 
 3          2019     C          10         

我的预期输出应该是这样的:

 id_skill | year | skill | count_comp_conf | count_cancel | count_missed
 ------------------------------------------------------------------------
 1          2018     A          20             5                 1  
 2          2018     B          15             8                 0  
 1          2019     A          10             4                 1  
 2          2019     B          12             0                 5  
 3          2019     C          10             2                 2

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您可以使用conditional aggregation 使用case when expression

    SELECT a.id_skill, YEAR(a.ap_meet_date) As year, s.skill,
    COUNT(case when a.ap_status IN ('complete', 'confirm') then 1 end) as count_comp_conf,
    COUNT(case when a.ap_status = 'cancel' then 1 end) as count_cancel,
    COUNT(case when a.ap_status = 'missed' then 1 end) as count_missed
    FROM appointment a inner join skills_data s on a.id_skill=s.id_skill 
    GROUP BY `id_skill`, `year` 
    ORDER BY `YEAR` DESC
    

    【讨论】:

    • 或者只是 SUM(ap_status='cancel')
    • @Strawberry,这真的很好,但大多数时候我都忘记了:)
    • @fa06 成功了 非常感谢:) 但是只有最后一个条件后的逗号应该被删除(我的意思是在第四行的 count_missed 之后)。
    【解决方案2】:
    SELECT a.id_skill, 
       YEAR(a.ap_meet_date) As year, 
       s.skill,
       SUM(IF(a.ap_status IN ('complete', 'confirm'),1,0)) AS count_comp_conf,
       SUM(IF(a.ap_status='cancel',1,0)) AS count_cancel,
       SUM(IF(a.ap_status='missed',1,0)) AS count_missed
    FROM appointment a,skills_data s WHERE a.id_skill=s.id_skill 
    GROUP BY `id_skill`, `year` 
    ORDER BY `YEAR` DESC;
    

    请尝试将 if 条件与 sum 一起使用。

    【讨论】:

    • 效果很好。谢谢 :) 1,0 在每个 IF 条件中意味着什么
    • if 中,您的条件匹配,它将为每行返回 1 或 0。然后使用 sum 函数。谢谢!
    【解决方案3】:

    通过以下查询,您将获得输出。

    select id_skill ,
    year , 
    skill , 
    count_comp_conf , 
    count_cancel , 
    count_missed ( select id_skill, year, skill, if ap_status ='Completed' then count_comp_conf+1, elseif ap_status ='cancelled' then count_cancel +1 else count_missed+1
        from appointment a join skills_data s on (a.id_skill = s.id_skill) group by id_skill, year) group by id_skill,year 
        order by year desc;
    

    【讨论】:

    • 可以合理地假设答案与 OP 的问题有关,而无需明确说明。
    猜你喜欢
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多