Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MYSQL LEFT JOIN and COUNT and GROUP BY

I found several threads concerning that task, but all don't really help me, or I'm not experienced enough to understand it.

I am using mysql and have two tables user and user_rh. I want a list (ordered by names) of usernames with the correspond number of entries in user_rh.

      `user`                `user_rh`
------------------     ------------------
| `uid` | `name` |     | `uid` | `zaid` |
------------------     ------------------
|   1   | Bob    |     |   2   |    4   |
|   2   | John   |     |   2   |    7   |
|   3   | Fred   |     |   3   |    2   |
|   4   | Peter  |     ------------------
------------------

So the result should look like:

--------------------
| `name` | `count` |
--------------------
| Bob    |    0    |
| Fred   |    1    |
| John   |    2    |
| Peter  |    0    |
--------------------

I tried this query:

SELECT
    `user`.`name`,
    `user_rh`.`uid`
FROM
    `user`
LEFT JOIN
    `user_rh`
ON (`user_rh`.`uid`=`user`.`uid`)
ORDER BY
    `user`.`name`

It is going in the right way, but this will not return count values:

------------------
| `name` | `uid` |
------------------
| Bob    |  NULL |
| John   |   2   |
| John   |   2   |
| Fred   |   1   |
| Peter  |  NULL |
------------------

I thought I just add the COUNT() and GROUP BY commands:

SELECT
    `user`.`name`, 
    COUNT(`user_rh`.`uid`) AS `count`
FROM
    `user`
LEFT JOIN
    `user_rh`
    ON (`user_rh`.`uid`=`user`.`uid`)
GROUP BY
    `user_rh`.`uid`
ORDER BY
    `user`.`name`

But it shows me something like this. First it delivers a sorted list of names that have count!=0 and the last entry of the list is the first entry of table user which has count=0.

------------------
| `name` | `uid` |
------------------
| John   |   2   |
| Fred   |   1   |
| Bob    |   0   |
------------------

I think, I'm just combining the commands in a wrong way.

like image 492
Sven Richter Avatar asked Jan 16 '15 14:01

Sven Richter


People also ask

Can we use count and GROUP BY together?

The use of COUNT() function in conjunction with GROUP BY is useful for characterizing our data under various groupings. A combination of same values (on a column) will be treated as an individual group.

Can we use GROUP BY and count together in SQL?

The GROUP BY statement is often used with aggregate functions ( COUNT() , MAX() , MIN() , SUM() , AVG() ) to group the result-set by one or more columns.

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.

Can we use GROUP BY in joins?

Using Group By with Inner JoinSQL Inner Join permits us to use Group by clause along with aggregate functions to group the result set by one or more columns. Group by works conventionally with Inner Join on the final result returned after joining two or more tables.


2 Answers

Your 2nd query is fine. Just group by the user from the first table. Otherwise you would turn your left join into an inner join

SELECT
    u.name, 
    COUNT(rh.uid) AS cnt
FROM
    `user` u
LEFT JOIN
    user_rh rh
    ON (rh.uid = u.uid)
GROUP BY
    u.uid, u.name
ORDER BY
    u.name
like image 145
juergen d Avatar answered Nov 14 '22 22:11

juergen d


  1. it does not transform your left join to an inner join. It is just grouping by your uid from user_rh when linked to user. You have 3 different uid (NULL, 2 and 1) that's why you have only 3 lines in your result.

  2. when you are using grouping clause, you can select only field with grouping aggregate (like COUNT, SUM, AVG..) or field available in the group clause. You can omit the grouping but Mysql will do the grouping itself but results can be unreliable since it will choose the first one available. That's why you have Bob displayed in your 3 lines result.

like image 43
A.D. Avatar answered Nov 14 '22 23:11

A.D.