-1

I asked this question few days ago on SO, but with no valid answer for it.

The problem was that the following 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, 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 

Is giving the following result:

enter image description here

But what I really want is to group by only patient_id so I can get only one row per one patient who was diagnosed earlier with Diabetes.

I searched a lot and found that I can use sub query inside this query.

So I came up with the following sub query:

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

The result was grouped by patient_id, and I got the 2 id that really want and not more. Even the patient with ID 0361 was diagnosed with multiple types of diabetes in each visit to the clinic, but it's id is shown once.

Now I want to take this sub query and add it to the initial one:

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 

But I've got the same result of the image above, where per example patient_id=0361 is shown in 4 rows, but I want is to be shown once, with the date of the first time he was diagnoised with Diabetes.

alim1990
  • 4,656
  • 12
  • 67
  • 130
  • The query looks like it's in a mess and without seeing data I'm not suprised that you got no answer previously. Maybe if you can boil down your question to something simpler, perhaps a join involving only 2-3 tables, it might be easier to get help here. – Tim Biegeleisen Jul 31 '17 at 05:54
  • Perhaps if you'd heeded the valuable advice afforded in comments – Strawberry Jul 31 '17 at 06:07
  • Guys I dont know how to create sql fiddles. Plus I have 6 tables. Will take an hour to create a fiddle right ? – alim1990 Jul 31 '17 at 06:19

2 Answers2

1
SELECT t.patient_id,
CONVERT(aes_decrypt(t4.patient_name_en, 'key1') USING utf8mb4) as patient_name_en,
mindate as date_of_visit, 
tt2.diagnosis_name,
max(ifnull(tt5.date_of_assessment, 'N/A')) as date_of_assessment,
ifnull(tt5.assessment_result, 0) as assessment_result 
FROM consultation t
LEFT JOIN visit tt3 ON tt3.visit_id = t.visit_id
LEFT JOIN diagnosis tt2 ON t1.diagnosis_id = tt2.diagnosis_id
INNER JOIN
(
    SELECT t1.patient_id,min(t3.date_of_visit) mindate
    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 
    WHERE t2.diagnosis_name LIKE '%Diabetes%' AND t1.clinic_id = '361'
    AND t3.visit_status="Active"
    GROUP BY t1.patient_id
)INNERTABLE ON t.patient_id=INNERTABLE.patient_id and INNERTABLE.mindate
LEFT JOIN patient t4 ON t4.patient_id = tt3.patient_id
LEFT JOIN diabetes_assessment t5 ON t5.patient_id = t4.patient_id

Try above query.

halfer
  • 19,824
  • 17
  • 99
  • 186
Sagar Gangwal
  • 7,544
  • 3
  • 24
  • 38
0

What is your final goal ?

Getting only patient_id, date_of_assessment ? then you need only "group by" 1 column. like :

select patient_id, min(date_of_assessment) from .... where ....  group by patient_id

If you need to list diagnosis on the same column, you will need to use specific mysql thing, like :

select patient_id, min(date_of_assessment), GROUP_CONCAT(diagnosis SEPARATOR ' ') from .... where ... group by patient_id

Things is you need to give the database a way to compute a value for column you are not grouping by. It can be sum, count, min, max, ....

wargre
  • 4,575
  • 1
  • 19
  • 35