【问题标题】:MySQL Search query with likeMySQL搜索查询与like
【发布时间】:2011-10-04 10:50:26
【问题描述】:

我有几个文本字段用于过滤数据的数据库表,每个文本字段都包含用冒号分隔的数字数据(例如'1:2:4:5:6:7:9')

id   |  title         |  field1                 | filed2     | field3            |
1    | Some title1    |1:2:3:4:5:6:7            |1:2:3:6:7   | 1:2:4:5:7:9:10:11 | 
2    | Some title2    |1:2:3:4:5:6:7:8:9:10:11  |1:2:3:4:5:6 | 1:2:4:5:7:9:10:11 |
3    | Some title3    |1:2:3:4:5:6:7            |1:2:3:6:9   | 1:2:4:5:7:9:10:11 |
4    | Some title4    |3:4:5:6:7:10:11          |1:2:3:10:11 | 1:2:4:5:7:9:10:11 |
5    | Some title5    |1:2:3:4:5:6:7            |1:2:3:6:7   | 1:2:4:5:7:8:9:11  |
6    | Some title6    |2:3:4:5:6:7:9            |1:2:3:6:7   | 1:2:4:5:7:9       |

使用搜索表单,我为 field1、field2 和 field3 的每个参数使用复选框,并使用 php foreach 为每个字段创建 LIKE '%parameter%'

我的 SQL 查询看起来像 SELECT * FROM table WHERE (field1 LIKE '%1%' OR field LIKE '%2%' ) AND (field2 LIKE '%1%' OR field2 LIKE '%2%')

不幸的是,这个查询没有给我很好的结果,因为我得到了与我的想法不匹配的行:)

例如,如果用户选择了复选框值 1,2,3,4,5,6,7 查询只需要返回第 1 行、第 3 行和第 5 行

有没有更好的方法来过滤这个结果

问候

附加信息:

让我尝试向您解释一下这个想法
用户检查带有某些值(即 1、3、4、5、6、7)的复选框脚本只需要返回包含这些值的结果当用户选中控制 field2 和 field3 的其他复选框时,field1 也会发生同样的事情,但现在这并不重要

附加信息 pt2。

我会尽力给大家更好的解释我想要实现的目标

我有带有复选框和单选输入字段的搜索表单,每个复选框组(值从 1 到 10)代表表中的列(field1、field2、field3),列 field1 中的每个值例如代表选定的复选框(它们是在管理面板中为每一行设置)现在默认情况下所有复选框都被选中,当用户取消选择相应的复选框结果需要根据过滤器过滤行时,我现在得到所有结果 我尝试实现的好例子是http://www.hotelscombined.com/City/London.htm

因此,如果取消选中值为 2 的复选框,则它不能在结果中列出

BR 思乐

【问题讨论】:

  • 您是在寻找像 field1 = '1:2:3:4:5:6:7' 这样的完全匹配,还是如果复选框为 '2,3,4' 则想要第 1 行?
  • 我真的不明白你的问题。您可以重新编辑您的问题或以另一种方式改写它吗?你说的是checkbox values 1,2,3,4,5,6,7 query need to return only 1, 3 and 5th row。用户是否选择了第 1、3 和 5 个复选框?对糟糕的问题构建投反对票。
  • 是的,当用户只选中值为 1,2,3,4,5,6,7 的复选框时
  • 也许 SET 类型的列有意义? dev.mysql.com/doc/refman/5.1/en/set.html

标签: php mysql full-text-search


【解决方案1】:

使用 AND 代替 OR:

SELECT * FROM table WHERE (field1 LIKE '%1%' AND field LIKE '%2%' ) AND (field2 LIKE '%1%' AND field2 LIKE '%2%')

【讨论】:

    【解决方案2】:

    如您所见,field2 LIKE '%1%' 将匹配值为 2:10 的字段。为防止这种情况,请在字符串的结尾和开头添加冒号,然后搜索 LIKE '%:1:%' 其他可能的解决方案 - 在 SQL 中添加冒号以结束和开始 CONCAT(':',field2,':') LIKE '%:1:%'

    另一种方法是将数据库重构为类似

    main_table
    id   |title
    1    |some title
    
    link_table
    main_id|field|value
    1      |f1   |1     
    1      |f1   |2     
    1      |f2   |2     
    1      |f3   |1     
    1      |f3   |2    
    

    并进行查询以获取数据

    select id,title from main_table
    join link_table on main_table.id=link_table.main_id
    where (field = 'f1' and value in (1,2)) or (field = 'f2' and value in (2,3))
    

    因此,如果您使用当前的数据库设计,如果您需要获取在字段 1 中设置为“1,2,3,4,5,6,7”的所有行,您将需要进行类似的查询

    WHERE CONCAT(':',field1,':') LIKE '%:1:%' OR  
    CONCAT(':',field1,':') LIKE '%:2:%' OR 
    CONCAT(':',field1,':') LIKE '%:3:%' OR
    CONCAT(':',field1,':') LIKE '%:4:%' OR
    CONCAT(':',field1,':') LIKE '%:5:%' OR
    CONCAT(':',field1,':') LIKE '%:6:%' OR
    CONCAT(':',field1,':') LIKE '%:7:%'
    

    如果你像我说的那样重构,查询会像

    where field = 'f1' and value in (1,2,3,4,5,6,7)
    

    而且速度更快

    【讨论】:

      【解决方案3】:

      我认为问题在于%1% 不仅匹配1,还匹配1011 等。

      最好这样做:

      WHERE CONCAT(':', field1, ':') LIKE '%:1:%'
      

      【讨论】:

      • 当我在示例SELECT * FROM table WHERE CONCAT(':',field1,':') LIKE '%:1:%' OR CONCAT(':',field1,':') LIKE '%:3:%' 中使用它时,我得到了所有行,结果可能我不明白你的意思,你能用示例解释一下吗
      • @Sile 如果您的真实数据与您的样本相同,那么是的,这将返回所有 6 行。我认为你需要更好地解释你需要的逻辑:)
      • 这并不能解决问题,因为1 可以是1:2:3 中的第一个字符。要走这条路,您可能需要一个正则表达式,这意味着您不妨坚持当前格式。
      • @Michael 当第一个字符是 1 时,这应该很好用 :)
      • @Sile 我猜您只需要返回那些在 field1 中包含所有这些复选框的行,是吗?如果是,则使用 AND 运算符,而不是 OR
      猜你喜欢
      • 2013-05-27
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2023-03-16
      • 2015-05-26
      • 2014-10-18
      • 1970-01-01
      相关资源
      最近更新 更多