MySQL 查询或正则表达式仅找到模式 D、E、F
Posted
技术标签:
【中文标题】MySQL 查询或正则表达式仅找到模式 D、E、F【英文标题】:MySQL query or regexp find only pattern D, E, F 【发布时间】:2014-06-06 18:24:09 【问题描述】:我的 google-fu 让我失望了,如果有人可以为我指出正确的概念或术语方向,那就太好了。
我正在尝试从 mysql 数据库中获取行。假设我有一个等于 'DEF' 的变量。 我想以任意顺序在数据库中搜索仅包含 DEF 的记录。
示例列,
ABC
BC
D
DEX
DEF
DEFF
ED
EDF
FED
FEED
会回来的 D、DEF、ED、EDF、FED
【问题讨论】:
你的意思是排列吗? 'FFF` 不匹配? 为什么不用“FEED”和“DEFF”? @ÁlvaroG.Vicario 正确不匹配 @fancyPants 因为变量只有一个 E 和一个 F 问题也被标记为 php。我可以想到许多 SQL 方法来做到这一点......如果你事先知道排列。如果可以的话,我会考虑一些PHP preprocessing。 【参考方案1】:您需要的是一个用户定义的函数来检查字符串是否匹配。这是一个:
delimiter //
create function permutes(needles varchar(255), haystack varchar(255)) returns bool
begin
declare needles_position, first_occurance int;
set needles_position = length(needles);
while needles_position > 0 do
set first_occurance = instr(haystack, substring(needles, needles_position, 1));
if first_occurance = 0 then
return false;
end if;
set haystack = (select concat(substring(haystack,1,first_occurance-1), substring(haystack,first_occurance+1)));
set needles_position = needles_position - 1;
end while;
return true;
end//
现在你会得到你想要的:
select example_column from your_table where permutes(example_column ,'def');
该函数的作用是获取所有针字符并查看它们是否存在于大海捞针中。在检查下一根针之前,每根针都从大海捞针中取出,因此您不会得到双打。
【讨论】:
如果您希望区分大小写,请将第 7 行的instr(haystack
更改为 instr(binary haystack
原谅我的无知,但是那个功能是什么语言?
它被称为结构化查询语言,又名 sql ;) 。以为我不知道它是标准的还是mysql特定的sql。你可以把它放在工作台或 phpmyadmin 中。尽管在所有已知的数据库中,创建用户定义的函数都很常见。
哈!太好了,刚刚把这个功能添加到mysql中,效果很好。
这很有效,但删除了使用“_”进行通配符搜索的能力,我尝试了一下,看看我是否能弄明白。【参考方案2】:
我将把它留在这里,即使我意识到它并不能解决问题。它将接收'FEED'
。这个想法可能对其他人有所帮助。
您可以使用rlike
或regex
来做到这一点:
select *
from table t
where col rlike concat('[', 'DEF', ']+')
这是在构造简单的正则表达式'[DEF]+'
,这就是您想要的模式。
编辑:
如果你将原始字符串分解成字符,你可以这样做:
select t.col
from table t left outer join
(select 'D' as c union all select 'E' union all select 'F'
) c
on t.col like concat('%', c.c, '%')
group by t.col
having sum(c.c is null) = 0 and
sum(length(t.col) - length(replace(t.col, c.c, '')) > 1);
having
子句中的第一个条件检查所有字符是否都存在。第二个没有出现不止一次。请注意,如果有重复的字母进行比较,这将不起作用。
【讨论】:
+1 我会添加 HAVING CHAR_LENGTH(col) @StanislavL ...并因“喂食”而失败【参考方案3】:我总结了以下几种可能:
DEF
DFE
EDF
EFD
FDE
FED
REGEX (DEF|DFE|EDF|EFD|FDE|FED)
DF
DE
EF
ED
FE
FD
REGEX (DF|DE|EF|ED|FE|FD)
D
E
F
REGEX (D|E|F)
准确的查询是:
WHERE
COLUMN_NAME REGEXP '^(DEF|DFE|EDF|EFD|FDE|FED)$' OR
COLUMN_NAME REGEXP '^(DF|DE|EF|ED|FE|FD)$' OR
COLUMN_NAME REGEXP '^(D|E|F)$'
或者:
COLUMN_NAME
REGEXP '^(DE0,1F0,1|DF0,1E0,1|ED0,1F0,1|
EF0,1D0,1|FD0,1E0,1|FE0,1D0,1)$'
最短的:
REGEXP '^(D(E?F?|F?E?)|E(D?F?|F?D?)|F(D?E?|E?D?))$'
DEMO
【讨论】:
这不容易扩展...如果我们需要更长的列表怎么办,例如ABCDEFG
?
我没有比第二部分更短的解决方案,如果是,请尝试成为您的荣誉。
很好的解析解
@dlyaza:对我来说不是核心问题,但请记住 0,1
只是 ?
@Robin:我知道这一点,我想更像数学 m,n以上是关于MySQL 查询或正则表达式仅找到模式 D、E、F的主要内容,如果未能解决你的问题,请参考以下文章