php - MySql 两个表之间的 CROSS JOIN 并与另一个表匹配

标签 php mysql notifications

首先抱歉我的英语不好。我的场景如下:

我正在开发一个向许多用户发送通知消息的通知服务。我在 MySql 上有以下 3 个表

用户(user_id)

通知(notification_id, notification)

notifications_log(notification_log_id, notification_id, user_id)

每次用户阅读通知时,我都会在 notifications_log 表中插入一条记录,例如。 user_id = 2 的 John 用户阅读了 notification_id =3 的通知:“这是一个通知”,然后我在 notifications_lo 上插入一条记录g 与 user_id = 2notification_id = 3

一切正常,但我必须创建一个查询来获取所有未插入 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

demo here

此查询消除了您的派生表,减少了执行时间,并尽早执行交叉连接以减少正在操作的总行数。

但我建议重新考虑一下。一旦通知和用户表达到临界质量,这将创建数以百万计的行来过滤。

一个更好的主意是拥有一个 notification_inbox 表,作为您的 notifications_log 表的对应物。创建通知后,将其放入每个用户的收件箱表中。这样您就可以在单个表上执行简单的查询以确定每个用户的未读通知,而不是执行可能可怕的交叉连接

或者,单个 notification_delivery 表,而不是收件箱和日志表,它有一个“读取”标志。这也将允许有针对性的通知,以及向所有用户批量传送。

关于php - MySql 两个表之间的 CROSS JOIN 并与另一个表匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30363389/

相关文章:

php - 删除未关闭的 html 标签 - 同时将内容粘贴到带有 contenteditable 的 div

php - Symfony 如何用 Git 和 Composer 管理 Component 的子包?

mysql - 通过过滤查询对mysql查询进行排序

php - 如何使用 phpmyadmin 导出 MySQL 中的特定列?

javascript - 使用 ajax 和 php 向数据库添加值

android - cordova - 应用程序关闭时未收到 Android 推送通知

php - Laravel 依赖注入(inject) : When do you have to? 你什么时候可以模拟门面?两种方法的优点?

php - OOP PhP 类的空属性问题,当它们插入数据库时​​它们不为空。数据库

android - 捕获滑动以关闭事件

android - 收到通知时点亮屏幕android