Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting number of joined rows in left join

I'm trying to write an aggregate query in SQL which returns the count of all records joined to a given record in a table; If no records were joined to the given record, then the result for that record should be 0:

Data

My database looks like this (I'm not able to change the structure, unfortunately):

MESSAGE ---------------------------------------------- MESSAGEID   SENDER        SUBJECT ---------------------------------------------- 1           Tim           Rabbit of Caerbannog 2           Bridgekeeper  Bridge of Death  MESSAGEPART ---------------------------------------------- MESSAGEID   PARTNO        CONTENT ---------------------------------------------- 1           0             (BLOB) 1           1             (BLOB) 3           0             (BLOB) 

(MESSAGEPART has a composite PRIMARY KEY("MESSAGEID", "PARTNO"))

Desired output

Given the data above I should get something like this:

MESSAGEID   COUNT(*) ----------------------------------------------- 1           2 2           0 

It seems obvious that I need to do a left join on the MESSAGE table, but how do I return a count of 0 for rows where the joined columns from MESSAGEPART are NULL? I've tried the following:

Logic

I've tried

SELECT m.MESSAGEID, COUNT(*) FROM MESSAGE m LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID GROUP BY m.MESSAGEID; 

However, this returns

MESSAGEID   COUNT(*) ----------------------------------------------- 1           2 2           1 

I've also tried

SELECT mp.MESSAGEID, COUNT(*) FROM MESSAGE m LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID GROUP BY mp.MESSAGEID; 

but this returns

MESSAGEID   COUNT(*) ----------------------------------------------- 1           2             1 

What am I doing wrong here?

like image 566
errantlinguist Avatar asked Nov 21 '13 11:11

errantlinguist


People also ask

How do I count the number of rows in a SQL join?

The SQL COUNT() function returns the number of rows in a table satisfying the criteria specified in the WHERE clause. It sets the number of rows or non NULL column values.

How many rows left join returns?

The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in the right table; the join will still return a row in the result, but with NULL in each column from the right 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.


1 Answers

How about something like this:

SELECT m.MESSAGEID, sum((case when mp.messageid is not null then 1 else 0 end)) FROM MESSAGE m LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID GROUP BY m.MESSAGEID; 

The COUNT() function will count every row, even if it has null. Using SUM() and CASE, you can count only non-null values.

EDIT: A simpler version taken from the top comment:

SELECT m.MESSAGEID, COUNT(mp.MESSAGEID) FROM MESSAGE m LEFT JOIN MESSAGEPART mp ON mp.MESSAGEID = m.MESSAGEID GROUP BY m.MESSAGEID; 

Hope that helps.

like image 199
Mark J. Bobak Avatar answered Oct 03 '22 22:10

Mark J. Bobak