我有3张桌子。
Users
id | Name
----------
1 | Richard
2 | Mark
3 | John
4 | Victor
5 | James
Airtime
id | User_id |Amount
-------------------
1 | 1 | 40
2 | 3 | 30
3 | 4 | 47
Messages
id | User_id |Msg
-------------------
1 | 2 | Hello
2 | 3 | How are You
3 | 1 | Wassup?
4 | 3 | Hello guys
我需要显示用户列表及其通话时间(如果他们没有显示0)以及消息计数(例如,用户ID 3有2条消息,因此它应显示2)。
我需要将结果作为
Userid | Name |Msg Count | Airtime
1 | Richard | 1 | 40
2 | Mark | 1 | 0
3 | John | 2 | 30
4 | Victor | 0 | 47
5 | James | 0 | 0
到目前为止,这是我尝试过的,但它仅返回同时拥有消息和播放时间的用户的结果。
SELECT
airtime.amount AS credit,
COUNT(messages.id) AS msgcount,
users.*
FROM `users`
LEFT JOIN airtime ON users.id = airtime.user_id
LEFT JOIN messagelog ON users.id = messages.by
GROUP BY messagelog.by DESC
任何帮助将不胜感激。
答案 0 :(得分:2)
好吧,正如您似乎已经想到的那样,您需要在users表上进行外连接,因为您需要有关 ALL 用户的信息,无论他们是否在其他两个表中都有信息
在许多情况下,首先将问题分解为两部分是有帮助的。查找每个用户的播出时间并不太难,因为您可以按user_id对该列和组进行求和,如下所示:
SELECT u.id, COALESCE(SUM(a.amount), 0) AS totalAirtime
FROM users u
LEFT JOIN airtime a ON a.user_id = u.id
GROUP BY u.id;
Coalesce是一个返回第一个非null值的函数。因此,在这种情况下,如果用户在通话时间表中没有任何记录,则totalAirtime列将为0.
接下来,查找每个用户的消息数量有点棘手。首先,您要编写一个子查询,该子查询获取该表中每个用户的消息计数:
SELECT user_id, COUNT(*) AS numMessages
FROM messages
GROUP BY user_id;
外部将users表连接到(使用coalesce)函数,为该表中不存在的用户获取0:
SELECT u.id, COALESCE(t.numMessages, 0) AS totalMessages
FROM users u
LEFT JOIN(
SELECT user_id, COUNT(*) AS numMessages
FROM messages
GROUP BY user_id) t ON t.user_id = u.id
GROUP BY u.id;
最后,您可以使用user_id列将此查询与上面的查询相关联,以获取您需要的所有值:
SELECT u.id, u.name, t1.totalMessages, t2.airtime
FROM user u
JOIN(
SELECT u.id, COALESCE(t.numMessages, 0) AS totalMessages
FROM users u
LEFT JOIN(
SELECT user_id, COUNT(*) AS numMessages
FROM messages
GROUP BY user_id) t ON t.user_id = u.id
GROUP BY u.id) t1 ON t1.id = u.id
JOIN(
SELECT u.id, COALESCE(SUM(a.amount), 0) AS totalAirtime
FROM users u
LEFT JOIN airtime a ON a.user_id = u.id
GROUP BY u.id) t2 ON t2.id = t1.id;
这是一个SQL Fiddle示例,如果它可以帮助您,它还包含所有中间步骤。
答案 1 :(得分:1)
你可以这样做
select
u.id,
u.name,
COALESCE(m.cnt,0) as `count`,
COALESCE(a.Amount,0) as Airtime
from users u
left join Airtime a on a.User_id = u.id
left join (
select
User_id,
count(*) as cnt
from Messages
group by User_id
)m on m.User_id = u.id
<强> DEMO 强>
答案 2 :(得分:0)
简单如下:
SELECT
SUM(COALESCE(airtime.amount,0) ) AS credit,
COUNT(messages.id) AS msgcount,
users.*
FROM users
LEFT JOIN airtime ON users.id = airtime.user_id
LEFT JOIN messages ON users.id = messages.user_id
GROUP BY users.id
ORDER BY msgcount DESC
答案 3 :(得分:0)
试试这个:
select u.id, u.name,
(select count(distinct m.id) from messages m where m.user_id = u.id) as 'Msg Count',
ifnull(a.amount, 0) as Airtime
from users u left join airtime a on (a.user_id = u.id);
&#13;