繁体   English   中英

MySQL查询以匹配多个模式

[英]MySQL query to match on multiple patterns

我正在尝试找出一种解决方案,在该解决方案中,我可以查询具有多种格式的字段的表,并且我的输入格式也可能会有所不同。

我有几个表具有相同的 PIN 列 (VARCHAR(20)),但在每个表中,格式可能不同,如下所示。 通常每个表只有一种格式,但您可以看到我可能遇到的所有不同的变体。

PIN               |  ID
---------------------------
01-123.040-111-2  |  5
01-123.04-111     |  6
003.242424242.23  |  7
01.1234.345.22    |  8
1234456789        |  9

我希望能够接受以下任何输入变体:

> 012304041112
> 01.3456.342.22
> 02-3232323.2331

也许某些输入格式会完全匹配,有些则不会。 所以这就是我的想法:

我正在使用 PHP,所以我可以去掉 -'s 和 .'s 或任何空格来获取原始数字,但我不知道如何与可能在列中的那个数字进行比较桌子。 如果有一种方法可以将数字与最有可能是理想的数字进行比较。

例如:

input of 647382627 would match on 64.738.262-7 in the database

另一种情况可能是有这样的输入:

12-25-9-123

它应该匹配的地方:

12-25-009-123

[编辑] 澄清我的意思 - 不同的县使用不同的包裹号模式。 一个县可能会使用:

XX-XXXX-XXX-XX

对于他们的模式,但在他们可能会使用的某些文件中说:

10-1234-5-2 where it translates to 10-1234-005-02

我们知道这适用于哪些县,但输入可能是

10123452 or 10-1234-005-02 or 10-1234-5-2

所以我不知道如何准确地进行比较。 我想如果你从输入和列中去除破折号和零,你可以接近,如果需要,只需返回几个匹配项即可。

使用 mysql,您可以在比较字段之前使用正则表达式从字段中删除所有非数字字符,例如:

REGEXP_REPLACE(pin, '[^0-9]', '')
= REGEXP_REPLACE(?, '[^0-9]', '')

哪里? 是您的搜索输入。

正则表达式'[^0-9]'表示:除0 , 1 , ..., 9之外的任何字符。

这应该可以解决您对问题的初始描述,但是它不会处理您提供的最后一个示例,其中'12-25-9-123'应该匹配'12-25-009-123' :为此,我们需要修改正则表达式。 我建议附加规则应该是:任何紧跟在-前面的0都应该被抑制。

这是修改后的正则表达式:

REGEXP_REPLACE(pin, '(-0+)|([^0-9])', '')

解释 :

            EITHER
(-0+)         a dash followed by at least one 0
|           OR
([^0-9]+)   any non-numeric character

这是您可以在此 db fiddle 中找到的示例:

 WITH mytable AS (
     SELECT '64.738.262-7' pin, '647382627' compare 
     UNION SELECT '12-25-9-123', '12-25-009-123'
     UNION SELECT 'abc', '12-25-009-123'
 )
 SELECT 
     pin,
     compare, 
    CASE 
        WHEN (REGEXP_REPLACE(pin, '(-0+)|([^0-9])', '') 
            = REGEXP_REPLACE(compare, '(-0+)|([^0-9])', ''))
        THEN 'match'
        ELSE 'no match'
    END result
 FROM mytable

pin          | compare       | result
:----------- | :------------ | :------- 64.738.262-7 | 647382627 | match
12-25-9-123 | 12-25-009-123 | match
abc | 12-25-009-123 | no match

(1) 情况解决思路

在 MySQL 表中创建一个生成的列,以仅存储pin列中的数字:

ALTER TABLE yourtable 
  ADD COLUMN pin_digits VARCHAR(20) 
  GENERATED ALWAYS AS (REGEXP_REPLACE(pin, '[^0-9]', '')) STORED;

然后在其上创建一个唯一索引以禁止重复:

ALTER TABLE yourtable ADD UNIQUE INDEX uq_idx_pin_digits (pin_digits);

在比较(通过尝试插入)您的输入与存储的数据时,您现在可以从这个索引中受益:

INSERT INTO yourtable (pin) VALUES (REGEXP_REPLACE(?, '[^0-9]', '')); 
-- where ? is your input value passed from PHP (without any changes)
-- this will yield an error on unique constraint if the value already exists

现场演示

单击此处查看它是如何工作的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM