SQL .如何查找字符串值几乎相同的记录?
SQL .How to find records with almost identical string values?
假设我有这个 table(产品):
part_number product_name
1202 airpods
1204 ipod
1398 iphone 6
1304 watch I
1378 iphone 7
1244 airpods 2
我想 select part_number
至少有一个(几乎完美)匹配的所有记录,第三个字符除外。所以最终结果看起来像这样:
part_number product_name
1204 ipod
1398 iphone 6
1378 iphone 7
1244 airpods 2
有没有办法使用 LIKE 运算符来做到这一点?我知道 LIKE 可以在陈述几个已知字符时找到模式,但在这种情况下我不一定知道它们是什么。
注意:是的,part_number 字段定义为字符串,而不是数字。
我知道您想要的行中存在另一行且部件号部分匹配:前两位数字和最后一位数字应该匹配,而第三位数字不同。
您可以使用 exists
。假设 part_number
是一个整数(因为它 应该是 ),你可以用算术来做到这一点:
select p.*
from products p
where exists (
select 1
from products p1
where
p1.part_number <> p.part_number
and p1.part_number / 100 = p.part_number / 100
and p1.part_number - p1.part_number / 10 * 10 = p.part_number - p.part_number / 10 * 10
)
您还可以使用字符串函数 - 这使查询更容易理解(尽管效率可能较低):
select p.*
from products p
where exists (
select 1
from products p1
where
p1.part_number <> p.part_number
and substr(p1.part_number, 1, 2) = substr(p.part_number, 1, 2)
and substr(p1.part_number, 4, 1) = substr(p.part_number, 4, 1)
)
Demo on DB Fiddle - 两个查询结果:
part_number | product_name
:---------- | :-----------
1204 | ipod
1398 | iphone 6
1378 | iphone 7
1244 | airpods 2
手头没有 SQLite,但在大多数 SQL 变体中都有效:
select * from test t1 where exists
(
select * from test t2 where t2.part_number != t1.part_number
and left(t1.part_number,2) = left(t2.part_number,2)
and right(t1.part_number,1) = right(t2.part_number,1)
)
您可以使用COUNT()
window函数:
select part_number, product_name
from (
select *,
count(*) over (partition by substr(part_number, 1, 2), substr(part_number, -1)) counter
from products
)
where counter > 1
参见demo。
结果:
| part_number | product_name |
| ----------- | ------------ |
| 1204 | ipod |
| 1244 | airpods 2 |
| 1398 | iphone 6 |
| 1378 | iphone 7 |
假设我有这个 table(产品):
part_number product_name
1202 airpods
1204 ipod
1398 iphone 6
1304 watch I
1378 iphone 7
1244 airpods 2
我想 select part_number
至少有一个(几乎完美)匹配的所有记录,第三个字符除外。所以最终结果看起来像这样:
part_number product_name
1204 ipod
1398 iphone 6
1378 iphone 7
1244 airpods 2
有没有办法使用 LIKE 运算符来做到这一点?我知道 LIKE 可以在陈述几个已知字符时找到模式,但在这种情况下我不一定知道它们是什么。
注意:是的,part_number 字段定义为字符串,而不是数字。
我知道您想要的行中存在另一行且部件号部分匹配:前两位数字和最后一位数字应该匹配,而第三位数字不同。
您可以使用 exists
。假设 part_number
是一个整数(因为它 应该是 ),你可以用算术来做到这一点:
select p.*
from products p
where exists (
select 1
from products p1
where
p1.part_number <> p.part_number
and p1.part_number / 100 = p.part_number / 100
and p1.part_number - p1.part_number / 10 * 10 = p.part_number - p.part_number / 10 * 10
)
您还可以使用字符串函数 - 这使查询更容易理解(尽管效率可能较低):
select p.*
from products p
where exists (
select 1
from products p1
where
p1.part_number <> p.part_number
and substr(p1.part_number, 1, 2) = substr(p.part_number, 1, 2)
and substr(p1.part_number, 4, 1) = substr(p.part_number, 4, 1)
)
Demo on DB Fiddle - 两个查询结果:
part_number | product_name :---------- | :----------- 1204 | ipod 1398 | iphone 6 1378 | iphone 7 1244 | airpods 2
手头没有 SQLite,但在大多数 SQL 变体中都有效:
select * from test t1 where exists
(
select * from test t2 where t2.part_number != t1.part_number
and left(t1.part_number,2) = left(t2.part_number,2)
and right(t1.part_number,1) = right(t2.part_number,1)
)
您可以使用COUNT()
window函数:
select part_number, product_name
from (
select *,
count(*) over (partition by substr(part_number, 1, 2), substr(part_number, -1)) counter
from products
)
where counter > 1
参见demo。
结果:
| part_number | product_name |
| ----------- | ------------ |
| 1204 | ipod |
| 1244 | airpods 2 |
| 1398 | iphone 6 |
| 1378 | iphone 7 |