简体   繁体   中英

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

I have two tables namely "appointment" and "skills_data".

Structure of appointment table is:

id_ap || ap_meet_date || id_skill || ap_status. 

And the value of ap_status are complete, confirm, cancel and missed.

And the skills_data table contains two columns namely:

id_skill || skill

I want to get the count of total number of appointments for each of these conditions

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

GROUP BY id_skill and year and 
order by year DESC

I tried this query which only gives me count of one condition but I want to get other two based on group by and order by clauses as mentioned.

If there is no record(for example: zero appointments missed in 2018 for a skill) matching for certain conditions, then it should display the output value 0 for zero count.

Could someone please suggest me with a query whether I should implement multiple select query or CASE clause to achieve my expected results. I have lot of records in appointment table and want a efficient way to query my records. Thank you!

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

Output from my query:

 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         

My expected output should be like this:

 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

You can use conditional aggregation using 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
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;

Please try to use if condition along with sum.

With below query you will get output.

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM