Mysql 检索表中分隔的特定记录
我有一张桌子Mysql 检索表中分隔的特定记录,mysql,sql,Mysql,Sql,我有一张桌子 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| 我尝试过的问题 从表1中选择*,其中像%AA%C%这样的数据将检索第1,2,3,5,6行
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|
我尝试过的问题
从表1中选择*,其中像%AA%C%这样的数据将检索第1,2,3,5,6行
谢谢您可以使用通配符,但您必须像这样分隔表达式:
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|'
或者,您可以使用不使用索引的正则表达式。使用正则表达式的一点想法:
select * from table1 where data regexp '(\\|AA\\|)+.*(\\|C\\|)+';
如果我理解正确,您要问的是“获取与输入匹配的带分隔符的行”
所以,若输入是“AA”和“c”,那个么获取Data
列中的行,其结果将完全相同
| AA | C |
你可能会喜欢
select * from table1 where data = select concat('|',concat_ws('|','AA','C'),'|')
正则表达式解释
这是正则表达式“|%s”
假设在记录中:
- “空白”值不可忽略,即
|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
请参阅。您有什么问题?如果您正在尝试构建查询,哪种编程语言正在编写MySQL请求?请考虑使用正则表达式:您希望只包含AA和C?@仅出现AA和C的记录。。AA和C是用户输入。。也可以是其他任何东西“我不能改变模式”-我会回去挑战这个陈述所基于的前提。这种模式非常糟糕,非常难以使用,非常不可伸缩,并且与关系原则背道而驰,因此您可以转储RDBMS并从平面文件中工作。任何“要求”你保留现有模式的人显然都不知道他们在说什么,在他们造成任何损害之前,需要用线索棒在仓促中使劲一击。如果数据
存储为| C | AA |
?仅凭样本数据,你可以简单地选择3作为SNo,“|AA | C |”作为数据
。搜索列可能不需要是AA和C。用户可能会给出C和D。在这种情况下,长度(数据)=6可能不起作用。@Ank,对,6
。类似于LENGTH('AA |')+LENGTH('C |')-(2-1)
。
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