尝试以下查询之一:
SELECT a.phone_no
FROM admission a
JOIN users u on a.phone_no LIKE concat(u.phone_no, '__')
WHERE u.phone_no REGEXP '^(99)+[0-9]+$'
或
SELECT a.phone_no
FROM admission a
JOIN users u on a.phone_no REGEXP concat('^', u.phone_no, '[0-9]{2}$')
WHERE u.phone_no REGEXP '^(99)+[0-9]+$'
如果 “尾随数字” 的数量是不固定的,你也可以使用:
LIKE concat(u.phone_no, '%')
或
REGEXP concat('^', u.phone_no, '[0-9]*$')
但是在这种情况下,如果可能users.phone_no
是其他users.phone_no
(例如,其他的)的子序列,则可能需要使用SELECT DISTICT a.phone_no
。 99123和991234)。
更新
后运行一些测试用10K行对用户表和100K行,因为我来到了以下查询录取表:
SELECT a.phone_no
FROM admission a
JOIN users u
ON a.phone_no >= u.phone_no
AND a.phone_no < CONCAT(u.phone_no, 'z')
AND a.phone_no LIKE CONCAT(u.phone_no, '%')
AND a.phone_no REGEXP CONCAT('^', u.phone_no, '[0-9]*$')
WHERE u.phone_no LIKE '99%'
AND u.phone_no REGEXP '^(99)+[0-9]*$'
UNION SELECT 0 FROM (SELECT 0) dummy WHERE 0
fiddle
这种方式可以使用REGEXP
,仍然有很好的表现。这个查询几乎立即在我的测试用例中执行。
从逻辑上讲,您只需要REGEXP条件。但是在更大的表上查询可能会超时。使用LIKE条件将在REGEXP检查之前过滤结果集。但即使使用LIKE查询也不会很好。出于某种原因,MySQL不使用范围检查来进行连接。所以我加了一个明确的范围检查:
ON a.phone_no >= u.phone_no
AND a.phone_no < CONCAT(u.phone_no, 'z')
有了这个检查可以从连接的一部分去除LIKE条件。
UNION部分是DISTICT的替代品。 MySQL似乎将DISTINCT转换成了GROUP BY语句,该语句表现不佳。使用具有空结果集的UNION我强制MySQL在SELECT之后删除重复项。如果您使用固定数量的结尾数字,则可以删除该行。
您可以调整REGEXP模式,以您的需求:
...
AND a.phone_no REGEXP CONCAT('^', u.phone_no, '[0-9]{2}$')
...
AND u.phone_no REGEXP '^(99)+[0-9]{8}$'
...
如果你只需要REGEXP检查phone_no的长度,你也可以使用一个LIKE条件与“_”占位符。
AND a.phone_no LIKE CONCAT(u.phone_no, '__')
...
AND u.phone_no LIKE '99________$'
或者将LIKE条件与STR_LENGTH检查相结合。
你是什么意思,确切地说,“具有相同的模式”?从你的例子猜测,它实际上是“开始于”吗? – Bohemian
用户表和入场表都有相同的电话号码,以99开始,但用户表缺少结尾2位数。首先,我想过滤来自入场表'^ [99] + [0-9] {8}'的所有这些号码,然后将用户的电话号码9912678与入场的电话号码991267823 – shuvrow
匹配,如果我以这种方式查询用户表格的数据'9912678 | 9912323 | 9912366'查询执行正常,但我不知道该怎么做。谢谢 – shuvrow