【问题标题】:Problem with MySQL Select query with "IN" condition带有“IN”条件的 MySQL Select 查询的问题
【发布时间】:2011-02-16 16:52:50
【问题描述】:

我发现 MySQL select 语句在 where 子句中有“IN”的一个奇怪问题:

我正在尝试这个查询:

SELECT ads.* 
  FROM advertisement_urls ads 
 WHERE ad_pool_id = 5 
   AND status = 1 
   AND ads.id = 23 
   AND 3 NOT IN (hide_from_publishers) 
ORDER BY rank desc

在上面的 SQL 中 hide_from_publishers 是 ads_urls 表的一列,其值是逗号分隔的整数,例如4,2 或 2,7,3 等

因此,如果 hide_from_publishers 包含相同的上述两个值,它应该只返回“4,2”的记录,但它返回两个记录

现在,如果我将第二组的 hide_for_columns 的值更改为 3,2,7 并再次运行查询,它将返回正确输出的单个记录。

如果我在那里使用直接值而不是 hide_from_publishers,即 (2,7,3),它会识别并返回单个记录。

对这个奇怪的问题有什么想法还是我做错了什么?

【问题讨论】:

  • 发布查询会产生错误status = 1 and and ads.id = 23 double AND

标签: sql mysql


【解决方案1】:

元组(1, 2, 3) 和字符串"1, 2, 3" 是有区别的。前者是三个值,后者是一个字符串值,恰好在人眼中看起来像三个值。就 DBMS 而言,它仍然是一个值。

如果您希望多个值与记录关联,则不应将其作为逗号分隔值存储在单个字段中,而应将其存储在另一个表中并加入它。这样数据就保持结构化,您可以将其用作查询的一部分。

【讨论】:

    【解决方案2】:

    您需要将逗号分隔的hide_from_publishers 列视为字符串。您可以使用LOCATE 函数来确定您的值是否存在于字符串中。

    请注意,我在两个字符串中都添加了前导和尾随逗号,这样搜索“3”就不会意外匹配“13”。

    select ads.* 
        from advertisement_urls ads 
        where ad_pool_id = 5 
            and status = 1 
            and ads.id = 23 
            and locate(',3,', ','+hide_from_publishers+',') = 0
        order by rank desc
    

    【讨论】:

    • 痛苦,为什么不... and not find_in_set(3, hide_from_publishers) ...
    • @Marc B:同意,这对 MySQL 来说会更好。我猜我的想法更笼统。
    • thinking more generically - 这会导致 LIKE 子句不是 MySQL LOCATE 函数,对吗?
    • 这确实对我有用,但是通过调整,而不是和 locate(',3,', ','+hide_from_publishers+',') = 0 我不得不使用 concat: locate(',3 ,', concat(',',hide_from_publishers,',')) = 0 - 谢谢乔。我也会尝试使用 Mark 的 find_in_set,但现在 locate 似乎已经成功了
    • 哇 find_in_set 也很有魅力,感谢今天有两件事要学习关于 mysql :)
    【解决方案3】:

    您需要将值字符串拆分为单独的值。请参阅这个 SO 问题...

    Can Mysql Split a column?

    以及提供的示例...

    http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/

    【讨论】:

      【解决方案4】:
      猜你喜欢
      • 2011-10-25
      • 1970-01-01
      • 2013-08-28
      • 2020-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多