查询以检查两个数字是否共享前 n 个数字以另一个数字开头

问题描述

假设我有以下表格:

create table #Temp1(number int)
insert into #Temp1 values (12345),(123456),(1234567)

create table #Temp2(number int)
insert into #Temp2 values (123),(2345)

select * from #Temp1
select * from #Temp2
#Temp1        #Temp2
+---------+   +---------+
|  number |   |  number |
+---------+   +---------+
|  12345  |   |   123   |
|  123456 |   |  123456 |
| 1234567 |   |   2345  |
+---------+   +---------+

我想检查#Temp1.number 是否以#Temp2.​​number 开头。像这样:

+-------------+------------+
| this number | found here |
+-------------+------------+
|    123      |    12345   |
|    123      |    123456  |
|    123      |   1234567  |
|   123456    |    123456  |
|   123456    |   1234567  |
+-------------+------------+

注意: 2345 未找到,因为 #Temp1 中没有任何数字以 2345 开头

解决方法

似乎您只需要转换为 varchar,然后使用 LIKE

SELECT T1.number,T2.number
FROM #Temp1 T1
     JOIN #Temp2 T2 ON CONVERT(varchar(20),T1.number) LIKE CONVERT(varchar(20),T2.number) + '%';

请注意,由于进行了转换,这对于大型数据集将不起作用,因为查询不是 SARGable。

,

实际上我们可以避免将两个数字转换为字符串,而是使用 LOG10POWER 进行直接数值比较:

SELECT t1.number,t2.number
FROM Temp1 t1
INNER JOIN Temp2 t2
    ON t1.number >= t2.number
WHERE
    t1.number / POWER(10,FLOOR(LOG10(t1.number)) - FLOOR(LOG10(t2.number))) - t2.number = 0;

screen capture from demo link below

Demo

这里的逻辑例如要检查 12345 是否以 123 开头,首先要弄清楚前者比后者大多少个十位。在本例中,它是 100 的因数。因此,我们将 12345 除以 100 得到 123,然后我们发现它与第二个表中的前缀匹配。