Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

MySQL count group_concat using case

I have students work system. Each student can submit multiple assignments, and the assignments are either written or practical. For each student, I need to know who has ONLY submitted practical work, no written work.

I have two tables in use: assignments and workTypes.

assignments looks something like this (excuse date format):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

userid   workID   submissionDate
--------------------------------
1        254      1/1/2022
1        723      0000-00-00
1        435      3/1/2022
1        845      4/2/2022
2        254      6/2/2022
2        435      2/6/2022
2        923      0000-00-00
2        845      6/2/2022

WorkTypes looks something like this:

workID     type
--------------------
254        written
435        practical
845        written
723        written
923        practical

SQL Executed:

SELECT 
    assignments.userid,
    GROUP_CONCAT(case when workTypes.type = 'written' AND assignments.submissionDate IS NOT NULL AND assignments.submissionDate != '0000-00-00' then assignments.submissionDate end) AS 'writtenDates',
    COUNT('writtenDates') AS numWritten,
    GROUP_CONCAT(case when workTypes.type = 'practical' AND assignments.submissionDate IS NOT NULL AND assignments.submissionDate != '0000-00-00' then assignments.submissionDate end) AS 'practicalDates',
    COUNT('practicalDates') AS numPractical 
FROM `assignments` 
LEFT JOIN workTypes 
ON assignments.workID = workTypes.workID 
GROUP BY assignments.userid;

Expected Results:

userID    writtenDates        numWritten   practicalDates   numPractical
1         1/1/2022,4/2/2023   2            3/1/2022         1
2         6/2/2022,6/2/2022   2            2/6/2022         1

Once I have this data working, I want to add a clause to only select those results that have no written work but some practical, so something like:

HAVING numPractical > 0 AND numWritten < 1

At the moment, my query is returning the same number in the numWritten and numPractical fields for every student (4000+ students) which cannot be correct and also, the num fields are showing much higher numbers than there are dates, so for example I can see one row that has three dates in, but the numPractical field says 23. I am assuming 23 is the count of the number of rows of work for each student or something instead of the number of dates in the group_concat field, but I can’t work out why.

>Solution :

Use conditional aggregation with a boolean expression:

SELECT 
    a.userid,
    GROUP_CONCAT(CASE WHEN wt.type = 'written' AND a.submissionDate IS NOT NULL AND
                           a.submissionDate != '0000-00-00'
                      THEN a.submissionDate END) AS writtenDates,
    SUM(wt.type = 'written') AS numWritten,
    GROUP_CONCAT(CASE WHEN wt.type = 'practical' AND a.submissionDate IS NOT NULL AND
                           a.submissionDate != '0000-00-00'
                      THEN a.submissionDate end) AS practicalDates,
    SUM(wt.type = 'practical') AS numPractical 
FROM assignments a 
LEFT JOIN workTypes wt
    ON a.workID = wt.workID 
GROUP BY a.userid;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading