SELECT a.pid,
a.name,
COUNT(DISTINCT b.tid) talkingpoints,
COUNT(DISTINCT c.fid) facts
FROM people a
LEFT JOIN talkingPoints b
ON a.pid = b.pid
LEFT JOIN facts c
ON a.pid = c.pid
GROUP BY a.pid, a.name
ORDER BY a.pid
Join/merge 3 tables with count
Question
I have 3 tables:
people:
pid name
1 Cal
2 Example
3 Another
4 Person
talkingPoints:
tid pid talkingPoint
1 1 "..."
2 1 "..."
3 2 "..."
facts:
fid pid fact
1 3 "..."
2 2 "..."
And I'm trying to combine a count of talkingPoints and facts to 'people', for example:
pid name talkingPoints facts
1 Cal 2 null
2 Example 1 1
3 Another null 1
4 Person null null
(ordered by talkingPoints desc, then alphabetical, including 'people' rows which do not have any values for the counts)
I managed to combine 'people' with only one other table:
SELECT a.pid,a.name,
count(b.tid)
FROM people a, talkingPoints b
WHERE a.pid=b.pid
GROUP BY b.pid;
but that query ignores rows with a zero count (e.g. the row 'Person')
I hacked up this query which works correctly for 'talkingPoints' but I have not been able to adapt it to also combine 'facts' like my example table above.
select people.pid, people.name, x.talkingPoints from people left join
(select pid, name, count(name) talkingPoints from
(select people.pid, people.name from people
join talkingPoints on talkingPoints.pid = people.pid)
as talkingPoints group by talkingPoints.pid)
as x on x.pid = people.pid order by talkingPoints desc, people.name asc;
(probably a terrible way but it worked in the meantime)
How can I adapt my queries so they will output a table like my example?
Solution
OTHER TIPS
Using independent correlated subqueries in the SELECT clause avoids the duplicates caused by the joins:
SELECT pid,
name,
(SELECT COUNT(*)
FROM talkingPoints
WHERE pid = people.pid) AS talkingPoints,
(SELECT COUNT(*)
FROM facts
WHERE pid = people.pid) AS facts
FROM people