【问题标题】:SELECT entries if they don't match every entry in another table [edit]选择条目,如果它们不匹配另一个表中的每个条目[编辑]
【发布时间】:2023-01-16 18:56:48
【问题描述】:

我的 SQL 查询有问题。 我想选择每个有未读消息的用户。

我有三张桌子

  1. 用户
  2. 留言
  3. object_visited(有条目 [user_id,message_id],如果用户已阅读消息)

    所以我选择了消息,我需要的是每个用户

    1. 不在 object_visited(简单)中,或者
    2. 没有我选择的每条消息的条目。

      我面临的问题是,我根本无法想象我需要如何过滤并将这些表连接在一起以获得所需的结果。

      编辑:

      用户:

      user_id user_name
      11111 User1
      22222 User2
      33333 User3

      消息:

      message_id content
      aaaaa Hello World
      bbbbb This is a message
      ccccc test test 123

      object_visited:

      user_id message_id
      11111 aaaaa
      11111 bbbbb
      11111 ccccc
      33333 aaaaa
      33333 ccccc

      用户 1 已阅读所有消息,用户 2 未阅读任何消息,用户 3 未阅读bbbbb(这是一条消息).

      查询应返回:

      user_id
      22222
      33333

      因为他们没有针对每条消息的条目 object_visited。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您可以结合使用 LEFT JOIN、NOT IN 和 NOT EXISTS 来实现您想要的结果。

    首先,您需要使用 LEFT JOIN 将 users 表与 object_visited 表连接起来。这将确保所有用户都包含在结果中,即使他们在 object_visited 表中没有任何条目。

    然后,您需要使用 NOT IN 或 NOT EXISTS 来过滤掉在您选择的每条消息的 object_visited 表中都有条目的用户。以下是如何使用 NOT IN 编写查询的示例:

    复制代码

    SELECT users.user_id
    FROM users
    LEFT JOIN object_visited
    ON users.user_id = object_visited.user_id
    WHERE object_visited.message_id NOT IN (
        SELECT message_id FROM messages
    ) OR object_visited.user_id IS NULL
    

    此查询将从 users 表中选择所有用户,并使用 LEFT JOIN 将他们与 object_visited 表连接起来。然后它将过滤掉任何在 object_visited 表中为 messages 表中的每条消息具有条目的用户。

    或者,您也可以使用 NOT EXISTS

    复制代码

    SELECT users.user_id
    FROM users
    WHERE NOT EXISTS (
        SELECT 1 FROM messages
        WHERE NOT EXISTS (
            SELECT 1 FROM object_visited
            WHERE users.user_id = object_visited.user_id
            AND messages.message_id = object_visited.message_id
        )
    )
    

    此查询将从用户表中选择 user_id,其中在 messages 表中不存在任何 message_id,而在 object_visited 表中没有 user_id 条目。

    请注意,表名和列名可能与您的情况不同,因此您需要相应地进行调整。

    【讨论】:

      猜你喜欢
      • 2011-05-03
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多