views:

122

answers:

2

I have 2 tables, campaigns and campaign_codes:

campaigns: id, partner_id, status

campaign_codes: id, code, status

I want to get a count of all campaign_codes for all campaigns WHERE campaign_codes.status equals 0 OR where there are no campaign_codes records for a campaign.

I have the following SQL, but of course the WHERE statement eliminates those campaigns which have no corresponding records in campaign_codes ( i want those campaigns with zero campaign_codes as well)

SELECT 
    c.id AS campaign_id, 
    COUNT(cc.id) AS code_count
FROM 
    campaigns c
LEFT JOIN campaign_codes cc on cc.campaign_id = c.id
WHERE c.partner_id = 4
AND cc.status = 0
GROUP BY c.id
+3  A: 
SELECT 
    c.id AS campaign_id, 
    COUNT(cc.id) AS code_count
FROM 
    campaigns c
LEFT JOIN campaign_codes cc on cc.campaign_id = c.id
    AND c.partner_id = 4
    AND cc.status = 0
GROUP BY c.id
RedFilter
+2  A: 

I'd opt for something like:

SELECT 
    c.id AS campaign_id, 
    COUNT(cc.id) AS code_count
FROM 
    campaigns c
LEFT JOIN campaign_codes cc on cc.campaign_id = c.id
AND cc.status = 0 -- Having this clause in the WHERE, effectively makes this an INNER JOIN
WHERE c.partner_id = 4
GROUP BY c.id

Moving the AND to the join clause makes the join succeed or fail, crucially keeping resulting rows in where there is no matching row in the 'right' table.

If it were in the WHERE, the comparisons to NULL (where there is no campaign_code) would fail, and be eliminated from the results.

Rowland Shaw
Thanks! That did the trick. Would love an explanation or pointer to some reading on how the AND is being used.
k00k
What I am asking is if someone can explain or point me to a resource on placing the AND before the WHERE. Haven't used that in the past and not sure I really understand it.
k00k
@k00k added a bit more detail as to "why"
Rowland Shaw
@Rowland appreciate it, ta very much! :)
k00k