我有一张下表
SNo Data
1 |AA|B|C|D|E|
2 |AB|B|C|D|
3 |AA|C|
4 |AA|
5 |AA|AB|AC|C|
6 |AB|B|C|
数据由“|”分隔。我知道该表是非规范化的,但我无法更改模式。
用户将再提供一个输入。例如,如果用户将输入作为AA和C给出,则我必须仅检索仅出现AA和C而不是其他行的那些行 在这种情况下,我的输出将是
SNo Data
3 |AA|C|
我尝试过的查询
Select * from table1 where data like %AA%C%
将检索第1,2,3,5,6行
由于
答案 0 :(得分:2)
假设在记录中:
“空白”值不容忽视 - 即。 |AA||C|
与|AA|C|
不同;以及
没有重复的值 - 即。 |AA|C|AA|
永远不会发生。
然后你可以执行模式匹配并测试总值长度:
SELECT SNo
FROM my_table
WHERE data LIKE CONCAT('%|', 'AA', '|%')
AND data LIKE CONCAT('%|', 'C' , '|%')
AND CHAR_LENGTH(data) = 1 + CHAR_LENGTH('AA')
+ 1 + CHAR_LENGTH('C' )
+ 1
在sqlfiddle上查看。
答案 1 :(得分:0)
您可以使用通配符,但必须将表达式分开:
SELECT * FROM table1
WHERE data LIKE '%|AA|%' AND data LIKE '%|C|%'
这将获取包含|AA|
和|C|
的所有记录。但是,要限制仅匹配两者的行:
SELECT * FROM table1
WHERE data LIKE '%|AA|%' AND data LIKE '%|C|%'
AND LENGTH(data) = 6
如果您只有两个,您可以将它们键入并实际使用data
列上的索引:
SELECT * FROM table1
WHERE data = '|AA|C|' OR data = '|C|AA|'
可以将旧版本的MySQL优化为:
SELECT * FROM table1
WHERE data = '|AA|C|'
UNION ALL
SELECT * FROM table1
WHERE data = '|C|AA|'
或者,您可以使用不使用索引的正则表达式。
答案 2 :(得分:0)
使用正则表达式的一点想法:
select * from table1 where data regexp '(\\|AA\\|)+.*(\\|C\\|)+';
答案 3 :(得分:0)
如果我理解正确,你要问的是“获取与分隔符匹配的行”。
因此,如果输入为“AA”和“c”,则获取Data
列将具有完全相同结果的行
|AA|C|
你可以这样做
select * from table1 where data = select concat('|',concat_ws('|','AA','C'),'|')
答案 4 :(得分:0)
$whereClause = array();
foreach( $input AS $search ){
$whereClause[] = sprintf("data REGEXP '|?%s|?'", $search);
}
$sql = "SELECT * FROM tbl WHERE ".implode(" AND ", $whereClause);
这是正则表达式'|%s|'
。