我正在尝试找出一种解决方案,我可以在其中查询具有多种格式的字段的表,而且我的输入格式也可能会有所不同。
我有几个具有相同 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
[edit] 澄清我的意思—— 不同的县使用不同的包裹编号模式。一个县可能会使用:
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
这是您可以在 this 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
关于用于匹配多种模式的 MySQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54246113/