MySQL统计未读通知问题:关联双表的查询修正需求
问题分析与解决
原SQL的核心问题是逻辑运算符优先级错误,以及未正确处理LEFT JOIN后空值的情况:
AND优先级高于OR,原语句会被解析为(b.userId='916eb7e2-ee73-448f-9de0-024fe4de7aff' AND b.status=0) OR a.notificationType=1,导致即使定向通知已标记为已读(status=1),群发通知仍会被无差别计入,同时遗漏了未被标记(即b.notificationId IS NULL)的定向未读通知。- 未将
b.userId的条件放在JOIN子句中,导致LEFT JOIN过滤逻辑错误,无法保留未被当前用户标记的通知记录。
修正后的SQL语句
SELECT COUNT(a.notificationId) AS countUnread FROM tblnotifications AS a LEFT JOIN tblnotificationstatuses AS b ON a.notificationId = b.notificationId AND b.userId = '916eb7e2-ee73-448f-9de0-024fe4de7aff' WHERE (a.notificationType != 1 AND (b.notificationId IS NULL OR b.status = 0)) OR a.notificationType = 1;
逻辑说明
- JOIN子句优化:将
b.userId的条件移至LEFT JOIN的关联条件中,确保只关联当前用户的通知状态记录,保留所有通知的原始数据(包括未被标记的)。 - WHERE条件明确:
- 定向通知(
notificationType != 1):未读判定为无当前用户的状态记录(b.notificationId IS NULL),或状态标记为未读(status=0)。 - 群发通知(
notificationType = 1):全部计入未读统计(符合你更新后计数为2的需求)。
- 定向通知(
如果群发通知也需要按“未被标记为已读”统计,可改用以下语句:
SELECT COUNT(a.notificationId) AS countUnread FROM tblnotifications AS a LEFT JOIN tblnotificationstatuses AS b ON a.notificationId = b.notificationId AND b.userId = '916eb7e2-ee73-448f-9de0-024fe4de7aff' WHERE b.notificationId IS NULL OR b.status = 0;
内容的提问来源于stack exchange,提问作者user36514
相关产品推荐
相关产品推荐

