-3

I have this unanswered question where I had this erroneous result query:

SELECT
    t1.patient_id,
    CONVERT(aes_decrypt(t4.patient_name_en, :encKey) USING utf8mb4) as patient_name_en,
    min(t3.date_of_visit) as date_of_visit, 
    t2.diagnosis_name,
    max(ifnull(t5.date_of_assessment, 'N/A')) as date_of_assessment,
    ifnull(t5.assessment_result, 0) as assessment_result 
FROM consultation t1
LEFT JOIN diagnosis t2
    ON t1.diagnosis_id = t2.diagnosis_id
LEFT JOIN visit t3
    ON t3.visit_id = t1.visit_id
LEFT JOIN patient t4
    ON t4.patient_id = t3.patient_id
LEFT JOIN diabetes_assessment t5
   ON t5.patient_id = t4.patient_id
WHERE
   t2.diagnosis_name LIKE :diagName AND
   t1.clinic_id = :cid AND
   t3.visit_status=:visit_status
GROUP BY
    t1.patient_id,
    t2.diagnosis_name,
    t3.date_of_visit
    t4.patient_name_en,
    t5.date_of_assessment
    t5.assessment_result
ORDER BY t5.date_of_assessment DESC 

Which gives me this result:

enter image description here

The new thing is that I tried the following query using sub query to loop through patient_id:

SELECT t1.patient_id,
    CONVERT(aes_decrypt(t4.patient_name_en, 'key1') USING utf8mb4) as patient_name_en,
    min(t3.date_of_visit) as date_of_visit, 
    t2.diagnosis_name,
    max(ifnull(t5.date_of_assessment, 'N/A')) as date_of_assessment,
    ifnull(t5.assessment_result, 0) as assessment_result 
FROM consultation t1
LEFT JOIN diagnosis t2 
    ON t1.diagnosis_id = t2.diagnosis_id
LEFT JOIN visit t3 
    ON t3.visit_id = t1.visit_id
LEFT JOIN patient t4 
    ON t4.patient_id = t3.patient_id
LEFT JOIN diabetes_assessment t5 
    ON t5.patient_id = t4.patient_id
WHERE t1.patient_id IN 
(SELECT t1.patient_id
FROM consultation t1
LEFT JOIN diagnosis t2 ON t1.diagnosis_id = t2.diagnosis_id
LEFT JOIN visit t3 ON t3.visit_id = t1.visit_id
LEFT JOIN patient t4 ON t4.patient_id = t3.patient_id
LEFT JOIN diabetes_assessment t5 ON t5.patient_id = t4.patient_id
WHERE t2.diagnosis_name LIKE '%Diabetes%' AND t1.clinic_id = '361'
AND t3.visit_status="Active"
GROUP BY t1.patient_id) AND
t2.diagnosis_name LIKE '%Diabetes%' AND t1.clinic_id = '361'
AND t3.visit_status="Active"
GROUP BY t1.patient_id, t5.date_of_assessment, t4.patient_name_en, t3.date_of_visit, t2.diagnosis_name, t5.assessment_result
ORDER BY t5.date_of_assessment DESC 

And I've got the same result shown at the image above.

Here is the an sql fiddle about my problem

What I really want is to show only the following two rows which means group by patient_id.

enter image description here

And for few reasons, I cannot disable the only_full_group_by mode,because I read it may give some faulty result.

I tried to only group by patient_id in the fiddle and apparently it works properly because the fiddle has the only_full_group_by disabled.

What should I do ?

  1. Create a PHP solution where I break the query into 2, the first one is the sub query where I will get the IDs and then use the outer query in a foreach to get a row for each ID using LIMIT 1 ?
  2. Or disable the only_full_group_by mode which will affect my other queries in my application on different aspects ?
  3. Create an sql stored procedure instead of the solution #1 ?
alim1990
  • 4,656
  • 12
  • 67
  • 130
  • This query is a mess, and I won't attempt an answer, but I will ask why do you expect that turning off `only_full_group_by` mode would _break_ anything? It is allowing for a more lax type of query, but the existing queries which properly use `GROUP BY` should not be affected (I think). – Tim Biegeleisen Aug 01 '17 at 05:58
  • 1
    The query is a simple left joins for multiple tables. That's it. – alim1990 Aug 01 '17 at 06:04
  • is not clear your goal .. why you want only the two rows for the patients .. why not the others diagnosis .. ????? .. try explain what you want .. .you want the first diagnosis ???? – ScaisEdge Aug 01 '17 at 06:05
  • because I am searching only for patients who have `diabetes` and sometimes a patient is diagnosed with different types of it. What I want is to take the first visit when he was diagnosed of whatever type of them and display it. See the id=`361-9001`, he was diagnosed with two types, what I care about is to show one row with the first date – alim1990 Aug 01 '17 at 06:06
  • To fix the group by errors, just stop selecting non aggregate columns. You may need a subquery for the non aggregate columns causing the problem. – Tim Biegeleisen Aug 01 '17 at 06:08
  • then way your are grouping by t3.date_of_visit ... is you do so .. you have all the rows .. try remove this condition form group by – ScaisEdge Aug 01 '17 at 06:10
  • And how to know which columns are a non aggregate. – alim1990 Aug 01 '17 at 06:10
  • the columns that have not aggregation function (min, max, count ...) – ScaisEdge Aug 01 '17 at 06:12
  • anyway if you need the rows with min(date_of_visit) you should add your schema .. for see how select this subset or values from then related values – ScaisEdge Aug 01 '17 at 06:13
  • see the fiddle please, the schema is there – alim1990 Aug 01 '17 at 06:14
  • So guys, is it okay to disable the query and there is no need to change the other 45 queries that I already have in my project ? And No need to change any of them right ? – alim1990 Aug 01 '17 at 06:26

2 Answers2

0

The columns in the GROUP BY have to be the columns being returned. So instead of t5.assessment_resultit should just beassessment_resultbecause this is the alias of theIFNULL()` expression.

Also, you shouldn't include the results of aggregation functions in GROUP BY, so don't use t5.date_of_assessment or t3.date_of_visit there.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Try to use group_concat(column_name separator ', '). group_concat() doc

It will help concatenate rows based on youd desired group

Alexandru
  • 14
  • 2