2012-06-19 3 views
0

Во-первых, мои знания SQL немного ржавые. Я пытаюсь создать отчет об обзорах, которые каждый пациент прошел через определенный промежуток времени. Обзор проводится в рамках раунда врачей. Ниже приведены соответствующие таблицы с соответствующими столбцами: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 

Но, выше query возвращает строки, в которых число отзывов> 1. Я хочу, чтобы он возвращался, даже если число равно 0.

+0

Я не уверен, если то же самое относится и в PostgreSQL, но в T-SQL, подсчет на определенный столбце будет рассчитывать только не нулевые значения, и вместо этого будет использоваться отсчет (*). – Amalea

+1

@Amalea: То же самое в PostgreSQL. Таким образом, стандарт определяет функцию count() ' –

ответ

2

Самый простой способ присоединиться к таблицам и включить экземпляры, в которых нет совпадений в одной из этих таблиц, заключается в использовании LEFT OUTER JOIN. Это будет соответствовать всем записям слева, независимо от того, было ли совпадение найдено в правой части JOIN.

Поскольку ваш r.review_date находится в вашем предложении WHERE, совпадения не могут возникать, если нет обзора между этими датами. Таким образом, чтобы включить экземпляры, в которых нет обзора, вы должны разрешить это в своем предложении WHERE, добавив «OR r.review_date IS NULL», как показано ниже. Возможно, вы также захотите рассмотреть фильтрацию в поле round.date, чтобы вы рассматривали только случаи, когда в течение этого периода выполнялись действительные раунды. то есть. "WHERE ro.date между '2012-02-01' AND '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 

Примечание: Если вы хотите сообщить о записи без каких-либо раундов, вы также должны сделать первую присоединиться к 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 
+0

Это частично решает проблему, в этом случае этот запрос возвращает такое же количество записей, что и в таблице раундов. Что делать, если для пациента нет записей о раундах? Хотел также включить эти записи. Является ли это возможным? Спасибо за ответ. –

+0

В конце моего решения есть следующее примечание. Если вы хотите сообщать записи без каких-либо раундов, вам также придется сделать первый JOIN LEFT OUTER JOIN. Надеюсь, это ответ, который вы ищете. – Mazrick

+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.

+0

. Это частично решает проблему, в этом случае этот запрос возвращает такое же количество записей, что и в таблице раундов. Что делать, если для пациента нет записей о раундах? Хотел также включить эти записи. Является ли это возможным? Спасибо за ответ. –

Смежные вопросы