Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL - Counting rows and left join problem

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
like image 503
k00k Avatar asked Feb 02 '10 17:02

k00k


People also ask

Why the number of rows increase after left join?

There are two line items for ID 1003 in the second table, so the result of the join will be 2 line items. So, if your secondary tables have more than one row for the key you're joining with, then the result of the join will be multiple rows, resulting in more rows than the left table.

Does LEFT join change number of rows?

Left joins can increase the number of rows in the left table if there are multiple matches in the right table.

How do I join two tables and counts in SQL?

To achieve this for multiple tables, use the UNION ALL. select sum(variableName. aliasName) from ( select count(*) as yourAliasName from yourTableName1 UNION ALL select count(*) as yourAliasName from yourTableName2 ) yourVariableName; Let us implement the above syntax.

How do you get count in join query in MySQL?

If you have a table with members and this table has a column named "group_id", you can just run a query on the members table to get a count of the members grouped by the group_id. This should have the least overhead simply because you are avoiding a join but should still give you what you wanted.


2 Answers

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.

like image 138
Rowland Shaw Avatar answered Nov 02 '22 22:11

Rowland Shaw


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
like image 42
D'Arcy Rittich Avatar answered Nov 02 '22 23:11

D'Arcy Rittich