SQL报告连接三个表

时间:2012-06-19 15:19:33

标签: sql postgresql

首先,我的SQL知识有点生疏。我正在尝试生成每位患者在一段时间内完成的评估报告。审查是作为医生回合的一部分完成的。以下是具有相关列的相应表:

Patients: (id, name)

Rounds: (id, patient_id, date)

Reviews: (id, round_id, review)

报告应如下所示:

Patient     |     Reviews
_________________________

Patient 1   |   2
_________________________ 
Patient 2   |   1
_________________________ 
Patient 3   |   0
_________________________

我尝试了以下SQL语句:

SELECT 
    p.name as patient, 
    COUNT(r.round_id) as reviews
FROM 
    patients as p
    JOIN rounds as ro ON p.id = ro.patient_id
    JOIN reviews as r ON ro.id = r.round_id
WHERE 
    r.review_date between '2012-02-01' AND '2012-02-29'
GROUP BY 
    p.name

但是,上述查询仅返回评论计数为>的行。即使计数为0,我希望它返回。

2 个答案:

答案 0 :(得分:2)

SELECT  p.name AS patient
      , COUNT(r.ID) AS reviews
FROM    patients AS p
        LEFT JOIN rounds AS ro ON p.id = ro.patient_id
        LEFT JOIN reviews AS r ON ro.id = r.round_id
                                  AND r.review_date BETWEEN '2012-02-01'
                                                    AND     '2012-02-29'
GROUP BY p.name

将为您提供所有患者的清单,包括那些未在您的具体日期之间进行过一轮或复查的患者。没有回合或评论的患者将有0。

答案 1 :(得分:2)

加入表并包含其中一个表中不匹配的实例的最简单方法是使用LEFT OUTER JOIN。这将匹配左侧的所有记录,无论是否在JOIN的右侧找到匹配。

由于您的r.review_date位于WHERE子句中,因此除非在这些日期之间进行审核,否则不会发生匹配。因此,要包含没有检查的实例,必须在WHERE子句中通过添加“OR r.review_date IS NULL”来实现,如下所示。您可能还想考虑在round.date字段上进行过滤,以便您只查看在该时间范围内执行有效轮次的实例。即。 “在'2012-02-01'和'2012-02-29'之间的地方”

例如

SELECT
    p.name as patient, 
COUNT(r.round_id) as reviews
FROM 
    patients as p
    JOIN rounds as ro ON p.id = ro.patient_id
    LEFT OUTER JOIN reviews as r ON ro.id = r.round_id
WHERE 
    r.review_date between '2012-02-01' AND '2012-02-29' OR r.review_date IS NULL
GROUP BY 
    p.name

注意:如果你想报告没有任何回合的记录,你也必须让第一次JOIN成为LEFT OUTER JOIN。

FROM 
    patients as p
    LEFT OUTER JOIN rounds as ro ON p.id = ro.patient_id
    LEFT OUTER JOIN reviews as r ON ro.id = r.round_id