我有一张如下表格。
+------+----------+--------+
| id |sender_id |receiver_id|
+------+----------+--------+
| 1 | 1 | 4 |
| 2 | 1 | 34 |
| 3 | 4 | 1 |
| 4 | 11 | 8 |
| 5 | 24 | 4 |
| 6 | 11 | 5 |
+------+----------+--------+
我希望看到我的结果如下。
+------+----------+--------+
|user_id|sent |receive |
+------+----------+--------+
| 1 | 2 | 1 |
| 4 | 1 | 2 |
| 5 | 0 | 1 |
| 8 | 0 | 1 |
| 11 | 2 | 0 |
| 24 | 1 | 0 |
| 34 | 0 | 1 |
+------+----------+--------+
我想在一个表中显示我的结果,其中user_id列(所有唯一的sender_id& receiver_id)为user_id,发送(count(sender_id)为已发送,count(receiver_id))为receive。所以我可以在每个用户发送的一个表中得到一个结果&收到消息号码。 我正在尝试自我加入查询,但没有得到我预期的结果。
答案 0 :(得分:0)
我会使用此查询:
SELECT user_id, SUM(sent), SUM(receive)
FROM (
SELECT sender_id AS user_id, COUNT(*) AS sent, 0 AS receive
FROM tablename
GROUP BY sender_id
UNION ALL
SELECT receiver_id AS user_id, 0 AS sent, COUNT(*) AS receive
FROM tablename
GROUP BY receiver_id
) s
GROUP BY user_id
请参阅小提琴here。
答案 1 :(得分:0)
假设您有一个用户表,一种(低效但简洁)的方式是使用相关子查询:
SELECT user_id,
(SELECT COUNT(*) FROM messages WHERE sender_id = u.user_id) sent,
(SELECT COUNT(*) FROM messages WHERE receiver_id = u.user_id) received
FROM users u
另一种方法是JOIN
表并在聚合期间执行计数:
SELECT u.user_id,
SUM(m.sender_id = u.user_id) sent,
SUM(m.receiver_id = u.user_id) received
FROM users u JOIN messages m ON u.user_id IN (m.sender_id, m.receiver_id)
GROUP BY u.user_id
第三种(可能是最有效的)方式是首先以两种方式聚合表,然后加入结果:
SELECT user_id, m1.sent, m2.received
FROM users LEFT JOIN (
SELECT sender_id AS user_id, COUNT(*) AS sent
FROM messages
GROUP BY user_id
) m1 USING (user_id) LEFT JOIN (
SELECT receiver_id AS user_id, COUNT(*) AS received
FROM messages
GROUP BY user_id
) m2 USING (user_id)
但是,如果这是您希望经常在大型数据集上进行的操作,则可以考虑在users
表中缓存每个用户发送/接收的消息数(并且只需更新一次)发送新邮件。)