MySQL搜索查询与喜欢

时间:2011-07-13 12:11:17

标签: php mysql full-text-search

我有几个文本字段的数据库表,用于过滤数据,每个文本字段都包含用冒号分隔的数字数据(例如'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行

是否有更好的过滤此结果的解决方案

问候

其他信息:

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

其他信息pt2。

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

我有带复选框和无线电输入字段的搜索表单,每个复选框组(值1到10)表示表格中的列(field1,field2,field3),列field1中的每个值表示选中的复选框(这是在每个行的管理面板中设置)现在默认选中所有复选框,当用户取消选择相应的复选框结果需要根据过滤器过滤行时,我现在得到所有结果 我试图实现的好例子是http://www.hotelscombined.com/City/London.htm

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

BR 西莱

3 个答案:

答案 0 :(得分:1)

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

最好这样做:

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

答案 1 :(得分:0)

如您所见,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)

更快

答案 2 :(得分:0)

使用AND而不是OR:

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