Am试图对具有更多未读消息的用户进行排序,使其首先出现在mysql结果中,同时还包括具有已读消息的用户 最后出现
Am使用mysql 5.6.17 表结构
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| msgID | int(11) | NO | PRI | NULL | auto_increment |
| userID | int(11) | NO | | NULL | |
| msgText | varchar(255) | NO | | NULL | |
| msgStatus | varchar(255) | NO | | NULL | |
| userName | varchar(255) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
我的数据没有排序
+-------+--------+-------------------+-----------+----------+
| msgID | userID | msgText | msgStatus | userName |
+-------+--------+-------------------+-----------+----------+
| 1 | 1 | hi | unread | Francis |
| 2 | 2 | hello | unread | Emma |
| 3 | 1 | good | unread | Francis |
| 4 | 1 | your not easy | read | Francis |
| 5 | 2 | just no that | unread | Emma |
| 6 | 2 | don't lose it bro | unread | Emma |
| 7 | 2 | good keep it up | unread | Emma |
| 8 | 3 | i don't hate it | unread | John |
+-------+--------+-------------------+-----------+----------+
如果我运行组查询"select userID, userName FROM msg GROUP BY userID";
它将结果分组
+--------+----------+
| userID | userName |
+--------+----------+
| 1 | Francis |
| 2 | Emma |
| 3 | John |
+--------+----------+
但是我需要那些“ msgStatus”等于“未读”的人出现在顶部,以便甚至包括那些只对“ msgStatus”读过的人,在此先谢谢大家
select userID, userName FROM msg GROUP BY userID;
答案 0 :(得分:1)
按sum(msgStatus = 'unread')
降序排列:
select userID, userName
FROM msg
GROUP BY userID
order by sum(msgStatus = 'unread') desc
答案 1 :(得分:0)
我的方法是尝试为每个userId和userName计算一个未读计数和一个读计数。给定这4个计算列,您只需选择不同的 userId 即可优先选择未读计数为> 未读计数的行。如果MySql支持完全外部联接,则不会简化计算。这必须通过左右外部联接的联合来模拟:
SELECT DISTINCT userId, userName FROM (
SELECT sq1.userId,
sq1.userName,
sq1.unreadCount,
IFNULL(sq2.readCount,0) AS readCount FROM
(SELECT userId, userName, count(*) AS unreadCount FROM msg
WHERE msgStatus = 'unread'
GROUP BY userId, userName) sq1
LEFT JOIN
(SELECT userId, userName, count(*) AS readCount FROM msg
WHERE msgStatus = 'read'
GROUP BY userId, userName) sq2
ON sq1.userId = sq2.userId
UNION
SELECT sq2.userId,
sq2.userName,
IFNULL(sq1.unreadCount,0) AS unreadCount,
sq2.readCount FROM
(SELECT userId, userName, count(*) AS unreadCount FROM msg
WHERE msgStatus = 'unread'
GROUP BY userId, userName) sq1
RIGHT JOIN
(SELECT userId, userName, count(*) AS readCount FROM msg
WHERE msgStatus = 'read'
GROUP BY userId, userName) sq2
ON sq1.userId = sq2.userId
) sq
ORDER BY IF(unreadCount > readCount, unreadCount, 0) DESC, userId
;