使用子查询按特定列分组输出相同的错误结果

Posted

技术标签:

【中文标题】使用子查询按特定列分组输出相同的错误结果【英文标题】:Using sub query to group by specific column is outputting the same erroneous result 【发布时间】:2017-07-31 05:50:10 【问题描述】:

我在 SO 上询问了this question few days ago,但没有有效的答案。

问题在于以下查询:

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 

给出以下结果:

但我真正想要的是仅按 patient_id 分组,这样我只能为每个早期诊断为糖尿病的患者获得一行。

我搜索了很多,发现我可以在这个查询中使用子查询。

所以我想出了以下子查询:

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

结果按patient_id分组,我得到了真正想要的2个id,而不是更多。即使是ID为0361的患者,每次去诊所就诊时都被诊断出患有多种糖尿病,但它的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 

但我得到了与上图相同的结果,其中每个示例 patient_id=0361 显示在 4 行中,但我希望显示一次,以及他第一次被诊断出患有糖尿病的日期。

【问题讨论】:

查询看起来一团糟,而且没有看到数据,我并不惊讶您之前没有得到任何答案。也许如果您可以将您的问题归结为更简单的问题,也许是只涉及 2-3 个表的连接,那么在这里获得帮助可能会更容易。 如果您听取了 cmets 提供的宝贵建议,或许可以 伙计们,我不知道如何创建 sql fiddles。另外,我有 6 张桌子。制作小提琴需要一个小时吗? 【参考方案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

试试上面的查询。

【讨论】:

我会尝试并回复您。【参考方案2】:

你的最终目标是什么?

只获取 Patient_id、date_of_assessment 吗?那么你只需要“分组”1列。喜欢:

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

如果您需要在同一列上列出诊断,则需要使用特定的 mysql 事物,例如:

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

问题是您需要为数据库提供一种方法来计算您未分组的列的值。可以是 sum, count, min, max, ....

【讨论】:

以上是关于使用子查询按特定列分组输出相同的错误结果的主要内容,如果未能解决你的问题,请参考以下文章

sql子查询

具有多结果子查询的查询不适用于 jdbc

MDX 查询以对具有特定日期范围的日期维度进行分组

表连接和分组查询

MS Access 查询:合并特定字段列中具有相同数据的行

子查询&视图&事务