【问题标题】:SQL query at least one of somethingSQL 查询至少其中一项
【发布时间】:2010-07-07 17:32:56
【问题描述】:

我有一堆用户,每个用户都有很多帖子。 架构:

Users: id
Posts: user_id, rating

如何找到至少有一篇帖子评分高于 10 分的所有用户?

我不确定是否应该为此使用 subQuery,或者是否有更简单的方法。

谢谢!

【问题讨论】:

    标签: sql mysql database


    【解决方案1】:

    要查找至少有一篇帖子评分高于 10 的所有用户,请使用:

    SELECT u.*
      FROM USERS u
     WHERE EXISTS(SELECT NULL
                    FROM POSTS p
                   WHERE p.user_id = u.id
                     AND p.rating > 10)
    

    EXISTS 不关心其中的 SELECT 语句 - 您可以将 NULL 替换为 1/0,这会导致除以零时出现数学错误...但它不会,因为 EXISTS 只关心WHERE 子句中的过滤。

    相关性(WHERE p.user_id = u.id)是这被称为相关子查询的原因,除了评级比较之外,它只会返回 ID 值匹配的 USERS 表中的行。

    EXISTS 也更快,具体取决于具体情况,因为一旦满足条件,它就会返回 true - 重复无​​关紧要。

    【讨论】:

    • 你能给我解释一下吗?内部查询将获得任意数量的 NULL 行。然后,EXISTS 将其归结为 true 或 false,所以它不会只获取所有用户,还是没有用户?
    • @Jasie:EXISTS 不关心其中的 SELECT 语句 - 您可以将 NULL 替换为 1/0,这会导致除以零时出现数学错误......但它不会t,因为 EXISTS 只关心 WHERE 子句中的过滤。相关性(WHERE p.user_id = u.id)就是为什么这被称为相关子查询,除了评分比较之外,它只会返回 ID 值匹配的 USERS 表中的行。
    • @Jasie:EXISTS 也更快,视情况而定,因为一旦满足条件,它就会返回 true - 重复无​​关紧要。
    【解决方案2】:

    您可以加入表格以查找相关用户,并使用 DISTINCT 以便每个用户最多在结果集中出现一次,即使他们有多个评分 > 10 的帖子:

    select distinct u.id,u.username
    from users u inner join posts p on u.id = p.user_id 
    where p.rating > 10
    

    【讨论】:

      【解决方案3】:

      使用内连接:

      SELECT * from users INNER JOIN posts p on users.id = p.user_id where p.rating > 10;
      

      【讨论】:

      • 如果用户有多个帖子的评分超过 10,这将返回重复。添加 DISTINCT,或查看我的查询以获取替代信息。
      • 如果你只是想要一个用户列表,使用上面的但是用不同的 users.id 替换 *
      【解决方案4】:
      select distinct id
      from users, posts
      where id = user_id and rating > 10
      

      【讨论】:

        【解决方案5】:
        SELECT max(p.rating), u.id 
          from users u 
        INNER JOIN posts p on users.id = p.user_id 
        where p.rating > 10 
        group by u.id;
        

        此外,这会告诉您他们的最高评分是多少。

        【讨论】:

        • 抱歉 - 重新格式化以停止滚动。更容易阅读,更容易投票。
        • 谢谢,这样看起来更好。
        【解决方案6】:

        您的问题的正确答案是 OMG Ponies 的答案,WHERE EXISTS 更具描述性并且几乎总是更快。但是“SELECT NULL”对我来说看起来真的很丑而且违反直觉。我已将 SELECT * 或 SELECT 1 视为最佳实践。

        另一种方式,以防我们收集答案:

        SELECT u.id 
        FROM users u 
             JOIN posts p on u.id = p.user_id
        WHERE p.rating > 10
        GROUP BY u.id
        HAVING COUNT(*) > 1
        

        如果您测试的不是总是 1,这可能会很有用。

        【讨论】:

          猜你喜欢
          • 2022-01-16
          • 2018-09-17
          • 1970-01-01
          • 1970-01-01
          • 2011-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-23
          相关资源
          最近更新 更多