Firstly, my SQL knowledge is little rusty. I am trying to generate a report of reviews each patient has gone through for a time period. A review is done as part of a Doctors’ round. The following are the corresponding tables with relevant columns:
Patients: (id, name)
Rounds: (id, patient_id, date)
Reviews: (id, round_id, review)
The report should look like the following:
Patient | Reviews
_________________________
Patient 1 | 2
_________________________
Patient 2 | 1
_________________________
Patient 3 | 0
_________________________
I tried the following SQL statement:
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
But, the above query only returns rows where reviews count is > 1. I want it to return even if the count is 0.
The simplest way to Join the tables, and to include instances where there is no match in one of those tables, is to use a LEFT OUTER JOIN. This will match all records to the left, regardless of whether a match was found on the right side of the JOIN.
Since your r.review_date is in your WHERE clause, no matches can occur unless there is a review between those dates. So to include instances where there is no review, you must allow for that in your WHERE clause by adding “OR r.review_date IS NULL” as below. You may also want to consider filtering on the round.date field instead, so that you are only looking at instances where there were valid rounds performed within that time frame. ie. “WHERE ro.date between ‘2012-02-01’ AND ‘2012-02-29′”
eg.
Note: If you want to report records without any rounds, you will also have to make the first JOIN a LEFT OUTER JOIN as well.