这是我的表结构:
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
我正在尝试列出当前登录用户的所有票证。也就是说,仅由他们创建的票证。
此外,我还会显示一个小的颜色指示,让用户知道是否有任何未读消息。
因此,每当用户查看工单(通过从列表中单击)时,都会使用 ticket_id
和 在
以及当前时间)tblReadBy
中插入/更新记录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
我仍在尝试测试所有可能的情况。
最佳答案
我们可以使用SUM()
函数的 NULL
处理行为。如果不存在行,它将返回NULL
。
If the return set has no rows, SUM() returns NULL
MySQL 自动将 bool 比较运算符的结果类型转换为 0/1。利用这种行为,我们可以使用 Sum()
和 Coalesce()
.
SELECT
t.`ticket_id`,
t.`subject`,
t.`user_id`,
t.`created_date`,
t.`last_updated`
(
-- coalesce handles case when no rows
SELECT COALESCE(SUM(`ticket_id` > 0), 1)
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
关于mysql - 当不存在记录时,未读消息计数应返回非零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53249022/