Reputation: 163
I got a questions from a test, it seems an concept question or logic question, so no data at all. Please read:
Assuming there's no syntax error and the column names and table names are correct, what's wrong with the MySQL query below?
-- FOR EVERY USER WE HAVE, this is supposed to return the number of messages they sent
select u.user_id, sum(case when um.message_id is not null then 1 else 0 end) as number_of_messages_sent
from users u left join
users_messages um
on um.user_id = u.user_id
where um.status = 'sent'
group by u.user_id;
If anyone have any ideas, please help me.
Upvotes: 1
Views: 626
Reputation: 629
The column in the select
query is u.user_i
and the column in the group by
is u.user_id
Upvotes: 0
Reputation: 5993
What Went Wrong:
your query supposes to get EVERY user we have but it is only returning user who has sent messages. This is because your WHERE
clause filtered out the users who didn't send any messages. Let me illustrate this with an example.
Example:
I made some sample table with data using this code:
CREATE TABLE userz (
user_id int,
) ;
INSERT INTO userz (user_id)
VALUES
(1),(2),(3)
CREATE TABLE userz_messages(
message_id int,
user_id int,
status varchar(10)
)
INSERT INTO userz_messages (message_id,user_id,status)
VALUES
(1,1,'sent'),
(2,2,'sent'),
(3,3,'sent'),
(4,4,'notsend'),
(5,1,'sent'),
(6,2,'sent')
userz_table:
user_id
-----------
1
2
3
userz_message table:
message_id user_id status
----------- ----------- ----------
1 1 sent
2 2 sent
3 3 sent
4 4 notsend
5 1 sent
6 2 sent
when we perform your query we get this as the result:
user_id number_of_messages_sent
----------- -----------------------
1 2
2 2
3 1
Notice user with user_id 4 is not in the result set? This is what's wrong with the query. It is not getting EVERY user.
Hope my example helps you get a better understanding of your problem
Upvotes: 0
Reputation: 539
You are filtering all results with status="sent". Final result is not "all users and masseges". Final result is "All users who sent one or many massages".
This query is all users and the if exists their massages
SELECT u.user_id, COUNT(um.message_id)
FROM users AS u, users_messages AS um
WHERE um.user_id = u.user_id
GROUP BY u.user_id;
This query will return Users who sent at least 1 massage. U will not see users who have not sent massage yet.
SELECT u.user_id, COUNT(um.message_id)
FROM users AS u, users_messages AS um
WHERE um.user_id = u.user_id AND status="sent"
GROUP BY u.user_id;
Upvotes: 1
Reputation: 1270091
The where
clause is turning the left join
into an inner join
. So it is only returning users who have sent at least one message. That is not the intent of the question.
A better way to write the query uses count()
and fixes the problem by moving condition to the on
clause:
select u.user_id, count(um.message_id) as number_of_messages_sent
from users u left join
users_messages um
on um.user_id = u.user_id and um.status = 'sent'
group by u.user_id;
Upvotes: 1