I am trying to get all of the 'krits' for a specific member and get COUNT(id) the number of rows with kritID from 2 other tables.
This is what I have so far but it does not get accurate numbers it seems like the counts have been added to each other. In each of the returned kritID's.
Is it possible to get separate counts for each with a single SQL query?
SELECT krit.id, krit.short_url, COUNT(referring_url) AS views , COUNT(click_date) AS clicks
FROM ukritic_krits AS krit
LEFT JOIN ukritic_krits_stats AS views ON views.kritID = krit.id
LEFT JOIN ukritic_links_out AS clicks ON clicks.kritID = krit.id
WHERE (krit.memberID = '[LOGGED IN MEMBER ID]')
GROUP BY krit.id
P.S. Some of the returned counts my be 0 but I still need that value returned in the resulting rows
Try using COUNT(DISTINCT)
:
SELECT
krit.id, krit.short_url,
COUNT(DISTINCT views.id) AS views,
COUNT(DISTINCT click.id) AS clicks
FROM ukritic_krits AS krit
LEFT JOIN ukritic_krits_stats AS views ON views.kritID = krit.id
LEFT JOIN ukritic_krits_stats AS clicks ON clicks.kritID = krit.id
WHERE (krit.memberID = '[LOGGED IN MEMBER ID]')
GROUP BY krit.id
My guess is that the problem you're seeing is that the total counts will equal the number of views
multiplied by the number of clicks
, since every matching view
record is then left joined
to every matching clicks
record. By doing COUNT(DISTINCT)
, you only count each unique ID
instead of all the rows.
EDIT:
The query in your question changed, so since I have to edit anyways, it may be more efficient to use sub-selects in this case instead of LEFT JOINs
, since you would avoid a distinct operations... but you should of course test:
SELECT
krit.id,
krit.short_url,
(SELECT COUNT(*) FROM ukritic_krits_stats WHERE kritID = krit.id) AS views,
(SELECT COUNT(*) FROM ukritic_links_out WHERE kritID = krit.id) AS clicks
FROM ukritic_krits AS krit
WHERE (krit.memberID = '[LOGGED IN MEMBER ID]')
SELECT krit.id, krit.short_url,
SUM(CASE WHEN views.id IS NOT NULL THEN 1 ELSE 0 END) AS views,
SUM(CASE WHEN click.id IS NOT NULL THEN 1 ELSE 0 END) AS clicks
FROM ukritic_krits AS krit
LEFT JOIN ukritic_krits_stats AS views
ON views.kritID = krit.id
LEFT JOIN ukritic_krits_stats AS clicks
ON clicks.kritID = krit.id
WHERE (krit.memberID = '[LOGGED IN MEMBER ID]')
GROUP BY krit.id