【问题标题】:MySQL How to filter a query based on avoiding a particular resultMySQL如何根据避免特定结果来过滤查询
【发布时间】:2019-03-30 05:09:02
【问题描述】:

这是简化的等价物:

表: 用户日志

字段: log_id, 用户身份, 日志评论, log_created, 日志更新

我尝试了什么:

    SELECT * FROM user_log 
    WHERE user_id = 123 
    AND log_comment = "The one I want"
    AND NOT log_comment = "The one I don't want"

期望的结果: 理想情况下,我希望它从表中返回该用户 ID 的所有记录,如果它包含“我不想要的那个”的评论,则根本没有。

实际结果: 不工作。它所做的是返回带有注释“我想要的那个”的记录。

抱歉,如果标题不清楚,我不知道如何描述我的问题。

【问题讨论】:

  • 您的查询看起来不错。也许“你不想要的”有不同的形状和拼写错误?
  • @TheImpaler 我不认为你已经考虑过了。
  • 只是换个说法,用户可以拥有很多 cmets,其中一些可能是您想要的,而另一些可能是您不想要的。如果有后者,您根本不希望该用户使用任何后者。

标签: mysql sql database mariadb mysql-workbench


【解决方案1】:

我会使用NOT EXISTS

SELECT ul.*
FROM user_log ul
WHERE NOT EXISTS (SELECT 1 
                  FROM user_log ul1 
                  WHERE ul.user_id = ul1.user_id AND ul1.log_comment = "The one I don't want"
                 );

【讨论】:

    【解决方案2】:
    • 您可以使用Group ByHaving 子句使用基于条件聚合函数的过滤。在 Derived 表中,我们可以确定 user_id = 123 是否有任何带有 log_comment = "The one I don't want" 的行。
    • HAVING NOT SUM(log_comment = "The one I don't want") 确保 user_id 不存在这样的行。
    • 现在,只需将此 Derived 表结果集连接到 user_log 表,并仅获取 log_comment = "The one I want" 所在的行。
    • 如果 user_id 甚至有一行带有“我不想要的”;此查询不会返回任何单行。

    对 Group By 使用条件聚合:

    SELECT u1.* 
    FROM user_log AS u1 
    JOIN (SELECT u2.user_id 
          FROM user_log AS u2 
          WHERE u2.user_id = 123 
          GROUP BY u2.user_id 
          HAVING NOT SUM(u2.log_comment = "The one I don't want")
         ) AS dt ON dt.user_id = u1.user_id 
    WHERE 
      u1.log_comment = "The one I want"
    

    【讨论】:

    • 嗯,也许是这样。
    【解决方案3】:

    我会使用existsnot exists

    select ul.*
    from user_log ul
    where exists (select 1
                  from user_log ul2
                  where ul2.user_id = ul.user_id and
                        ul2.comment = 'The one I want'
                 ) and
          not exists (select 1
                      from user_log ul2
                      where ul2.user_id = ul.user_id and
                            ul2.comment = 'The one I don''t want'
                     ) ;
    

    【讨论】:

      【解决方案4】:
      SELECT * FROM user_log 
      WHERE user_id = 123 
      AND log_comment     LIKE "%The one I want%"
      AND log_comment NOT LIKE "%The one I don't want%"
      

      当我阅读你的描述时,这里有一些log_comment的例子

      “嘿,我想要的那个——是的!” -- 捕获这个
      “嘿,我想要的那个——是的,我想要的”——抓住这个
      “嘿,我不想要的那个——是的!” -- 跳过这个
      “嘿,我想要的那个。哦,等一下我不想要的那个”——跳过这个
      “我不想要的哦,等等——我想要的”——也跳过了

      如果这些不是正确的结果,那么用一组例子来澄清你的问题。

      【讨论】:

        【解决方案5】:

        我不确定我是否理解这个问题,但这是否可行:

        SELECT * FROM user_log 
        WHERE user_id = 123 
        AND log_comment not like "%The one I don't want%"
        

        【讨论】:

        • 这仍然会选择曾经评论过“我不想要的那个”的用户
        • 不,它只会拾取用户 123。
        • 所以如果这个用户123有多个cmet,其中一个是“我不要的那个”,你的查询还是会抓到这个用户,这是错误的。
        • OP 希望日志中从未出现过“我不想要的那个”的用户。
        • not like "%The one I don't want%" 怎么能捡到“我不想要的那个”?
        猜你喜欢
        • 1970-01-01
        • 2013-09-29
        • 2019-04-27
        • 1970-01-01
        • 2018-10-24
        • 1970-01-01
        • 2017-12-15
        • 2013-02-20
        • 1970-01-01
        相关资源
        最近更新 更多