搜索MySQL匹配m个字符串中的n个数字

时间:2015-02-18 00:58:03

标签: php mysql sql-server regex

我在MySQL数据库中有大约500万行与以下系统匹配

n1-n2-n3-n4-n5(例如8-23-43-12-3),其中每个数字对于该序列是唯一的。此外,每个数字的范围从1到99.

我需要一种方法来检索MySQL DB中的所有行,其中五个数字中的三个匹配。例如,用户输入4-23-65-82-3,我想返回共享输入的五个数字中的任意三个的所有行,因此 4 - 65 -12-49- 82 匹配,34- 23 -76- 3 - 65 匹配等

我的表格如下:

number_tableiduuidfive_numbersfirst_numbersecond_numberthird_numberfourth_numberfifth_number

到目前为止我尝试过:

  1. 遍历每一行,并匹配first_number为用户提交的五个数字中的任意一行的任何行。这不聪明!

  2. 与MySQL中的RegExp匹配,但这需要一个包含所有可能组合的SQL语句。这不是太聪明,但如果有人拥有更高效的MySQL REGEXP,我可以使用它。

  3. 我基本上在寻找一个SQL解决方案,因为我不必担心内存耗尽,SQL执行会更快,我想将它放在一个视图中,以便我可以执行一些命令。

    我为冗长的帖子道歉,但我想提供尽可能多的信息。

    谢谢!

3 个答案:

答案 0 :(得分:1)

假设您的用户输入为n1,n2,n3,n4,n5,您可以按如下方式编写SQL:

select id, uuid, five_numbers from
    (select *, 
        if(first_number in (n1,n2,n3,n4,n5), 1, 0)  +
        if(second_number in (n1,n2,n3,n4,n5), 1, 0) +
        if(third_number in (n1,n2,n3,n4,n5), 1, 0)  +
        if(fourth_number in (n1,n2,n3,n4,n5), 1, 0) +
        if(fifth_number in (n1,n2,n3,n4,n5), 1, 0) as total
     from number_table) as t 
where total >= 3

因此,如果五个数字中的任何一个具有该值,则将总数加1。然后,您可以使用包含3个或更多用户输入数字的数字过滤行

答案 1 :(得分:0)

MySQL FIELD函数在这里很有用:

SELECT id, uuid, five_numbers, 
FIELD(A, first_number , second_number , third_number , fourth_number , fifth_number) > 0 as aFound,
FIELD(B, first_number , second_number , third_number , fourth_number , fifth_number) > 0 as bFound,
FIELD(C, first_number , second_number , third_number , fourth_number , fifth_number) > 0 as cFound,
FIELD(D, first_number , second_number , third_number , fourth_number , fifth_number) > 0 as dFound,
FIELD(E, first_number , second_number , third_number , fourth_number , fifth_number) > 0 as eFound
FROM number_table
WHERE
(
first_number in (A, B, C, D, E)
OR second_number in (A, B, C, D, E)
OR third_number in (A, B, C, D, E)
)
AND aFound + bFound + cFound + dFound + eFound >= 3;

FIELD函数返回查找第一个参数的参数的索引,或者返回0.如果您选择(n > 0)作为参数,它将解析为TRUE MySQL将整数值视为1。因此,您可以将它们一起添加以检查值,而无需执行子查询。你可以通过'进行一些额外的表现。检查各个字段,这样您就不必根据整个表行集计算函数值。但是,您只需检查前三个字段,因为如果它至少与其中一个字段不匹配,则它可能无法匹配五个数字中的三个。

也可以简单地选择

SELECT * 
FROM number_table
WHERE
((LOCATE(A, five_numbers) > 0) +
(LOCATE(B, five_numbers) > 0) +
(LOCATE(C, five_numbers) > 0) +
(LOCATE(D, five_numbers) > 0) +
(LOCATE(E, five_numbers) > 0)) >= 3

答案 2 :(得分:0)

快速回答是:

SELECT * FROM 
(SELECT *,
 five_numbers REGEXP '^3-|-3-|-3$' as n1,
 five_numbers REGEXP '65' as n2,
 five_numbers REGEXP '82' as n3 
FROM `number_table`) as t 
WHERE t.n1+t.n2+t.n3=3

如果你需要我可以用PDO设置php代码,只需询问

相关问题