[英]MySql CROSS JOIN between two tables and match with another
首先,抱歉我的英语不好。 我的情况如下:
我正在开发一种将通知消息发送给许多用户的通知服务。 我在MySql上有以下3个表
users(user_id)
notifications(notification_id, notification)
notifications_log(notification_log_id, notification_id, user_id)
每次用户阅读通知时,我都会在notifications_log表上插入一条记录,例如。 具有user_id = 2
John用户读取了具有notification_id =3
的通知:“这是一个通知”,然后我在notifications_lo
user_id = 2
和notification_id = 3
notifications_lo
g上插入了一条记录。
一切正常,但我必须创建一个查询来获取未插入notifications_log的所有用户的所有通知。 我所拥有的是:
SELECT u.user_id, n.notification_id, n.notification, nl.notification_log_id
FROM users as u
LEFT JOIN notifications_log as nl ON nl.user_id = u.user_id
CROSS JOIN notifications as n
WHERE u.user_id NOT IN (SELECT nl.user_id FROM notifications_log as nl)
AND u.user_id = 1 /* test with user 1 */
如果用户1的notifications_log表上没有记录,查询结果将显示给我
user_id | notification | notification_id | notification_log_id
------------------------------------------------------------------------------
- 1 | Notification_1 | 1 | null
- 1 | Notification_2 | 2 | null
但是,如果我在notifications_log
为用户和notification_2插入至少1条记录,则结果为空,我应该得到:
user_id | notification | notification_id | notification_log_id
----------------------------------------------------------------------------
- 1 | Notification_1 | 1 | null
该查询似乎将notification_log_id与其他记录合并为空,notification_log_id ...
简而言之,我需要的是从某个特定用户获取所有未在表上插入的通知Notifications_log
提前致谢!
您想要的查询可能是以下查询:
select n.notification_id, u.user_id
from notifications n
cross join users u
left join notifications_log nl
on n.notification_id = nl.notification_id
and nl.user_id = u.user_id
where nl.notification_log_id is null
此查询消除了派生表,从而减少了执行时间,并尽早执行交叉连接以减少正在操作的行的总数。
但我建议您重新考虑一下。 一旦通知和用户表达到临界数量,这将创建数以百万计的行进行过滤。
一个更好的主意是拥有一个notification_inbox表,作为与notifications_log表相对应的表。 创建通知后,将其放置在每个用户的收件箱表中。 这样,您可以在单个表上执行简单的查询来确定每个用户的未读通知,而不是潜在地执行cross join
联接的可怕问题。
同样,也可以选择一个单独的notification_delivery表,而不是具有“ read”标志的收件箱和日志表。 这也将允许有针对性的通知,以及批量交付给所有用户。
似乎您走在正确的轨道上,但应该只在第二行到最后一行将user_id更改为notification_id :
SELECT u.user_id, n.notification_id, n.notification, nl.notification_log_id
FROM users as u
LEFT JOIN notifications_log as nl ON nl.user_id = u.user_id
CROSS JOIN notifications as n
WHERE n.notification_id NOT IN (SELECT nl.notification_id FROM notifications_log as nl)
AND u.user_id = 1 /* test with user 1 */
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.