这是我的表结构:
tblTickets
ticket_id | subject | creator_id | created_date | last_updated | category_id | ticket_status
tblMessages
msg_id | msg | ticket_id | replied_by | reply_time
tblReadBy - PrimaryKey: (ticket_id,user_id)
ticket_id | user_id | last_read_time
正在尝试列出当前登录用户的所有票证。也就是说,仅由他们创建的票证。
此外,正在显示一个小的颜色指示,以使用户知道是否有未读消息。
因此,每当用户查看故障单时(通过从列表中单击),将在记录tblReadBy
中将ticket_id
和user_id
与当前记录一起插入/更新。时间)
我的查询门票清单的查询看起来像这样:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT COUNT(*)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
此处,XXX
是当前登录用户的user_id。如果tblReadBy
表中当前登录的user_id
和ticket_id
中有一行,则此查询工作正常。
但是如果此user_id
和ticket_id
不存在任何行,则按照逻辑,这是“未读票证”,但查询将为0
返回has_unread_msg
列。
如何解决这种特殊情况?
注意::将有一个以上的用户答复票证。像实际的用户,主持人(不止一个),管理员等。
谢谢
解决方案:
到目前为止,我发现的是:
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
COALESCE(SUM(CASE WHEN `last_read_time` < t.`last_updated` THEN 1 ELSE 0 END), 1)
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX'
) AS `has_unread_msg`
FROM `tblTickets` AS t
WHERE t.`creator_id` = 'XXX'
ORDER BY t.`last_updated` DESC
我还在尝试测试所有可能的情况。
答案 0 :(得分:1)
我们可以使用SUM()
函数的[
{
"name": "refs/tags/wagner-test-3",
"newObjectId": "0000000000000000000000000000000000000000",
"oldObjectId": "aaaaab6cad84a07b7bd65cf3519142a12f856baa"
}
]
处理行为。如果没有行,它将返回NULL
。
如果返回集没有行,则SUM()返回NULL
MySQL自动将布尔比较运算符的结果类型转换为0/1。通过这种行为,我们可以使用NULL
和Coalesce()
。
Sum()
答案 1 :(得分:0)
之所以可行,是因为它离开了两个表的连接,以找出tblReadBy中是否有任何记录,然后在子查询中使用结果。不幸的是我无法测试。
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
您可能需要在外部查询的SELECT列表中添加r。ticket_id
,如下所示:
SELECT
t.`ticket_id`,
r.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
SELECT
CASE WHEN r.`ticket_id` IS NULL THEN 1
ELSE COUNT(*)
END AS message_count
FROM `tblReadBy`
WHERE `ticket_id` = t.`ticket_id` AND
`user_id` = 'XXX' AND
`last_read_time` < t.`last_updated`
) AS `unread_msg_count`
FROM `tblTickets` AS t
LEFT JOIN `tblReadBy` AS r ON t.`ticket_id` = r.`ticket_id` AND
r.`user_id` = 'XXX'
ORDER BY t.`last_updated` DESC
答案 2 :(得分:0)
正如我所见,您需要同时统计tblReadBy中已更新的消息和新消息且从未读取过的消息,即它们存在于tblTickets中,但不存在于tblReadBy中。
这是我的解决方案,有点复杂,我希望看到有人对其进行改进,但是基本上我又加入了两个“ SELECT ... COUNT(*)”,一个用于全新消息,一个用于更新>
SELECT t.ticket_id, subject, t.user_id, created_date, last_updated, IFNULL(c1.count, 0) + IFNULL(c2.count, 0)
FROM tblTickets t
LEFT JOIN (SELECT ticket_id, user_id, COUNT(*) count
FROM tblTickets t
WHERE NOT EXISTS (SELECT *
FROM tblReadBy r
WHERE t.ticket_id = r.ticket_id
AND t.user_id = r.user_id)
GROUP BY ticket_id, user_id) AS c1 ON c1.ticket_id = t.ticket_id AND c1.user_id = t.user_id
LEFT JOIN (SELECT r.ticket_id, r.user_id, COUNT(*) count
FROM tblReadBy r
JOIN tblTickets t ON t.ticket_id = r.ticket_id AND t.user_id = r.user_id
WHERE r.last_read_time < t.last_updated
GROUP BY r.ticket_id, r.user_id) AS c2 ON c2.ticket_id = t.ticket_id AND c2.user_id = t.user_id
WHERE t.user_id = 'aaa'