我有两个具有相同架构的表:
dbo.orders_1
| user_id | order_id | create_time |
|---------|----------|-------------------------|
| 1 | 5 | 2018-05-04 02:26:03.808 |
| 1 | 6 | 2021-01-01 02:26:03.821 |
| 2 | 12 | 2021-12-12 02:26:03.814 |
dbo.orders_2
| user_id | order_id | create_time |
|---------|----------|-------------------------|
| 6 | 7 | 2020-06-04 02:26:03.808 |
| 1 | 5 | 2021-01-01 02:26:03.821 |
| 3 | 4 | 2021-12-12 02:26:03.814 |
Run Code Online (Sandbox Code Playgroud)
这就是我如何找到两个表之间的重复行:
dbo.orders_1
| user_id | order_id | create_time |
|---------|----------|-------------------------|
| 1 | 5 | 2018-05-04 02:26:03.808 |
| 1 | 6 | 2021-01-01 02:26:03.821 |
| 2 | 12 | 2021-12-12 02:26:03.814 |
dbo.orders_2
| user_id | order_id | create_time |
|---------|----------|-------------------------|
| 6 | 7 | 2020-06-04 02:26:03.808 |
| 1 | 5 | 2021-01-01 02:26:03.821 |
| 3 | 4 | 2021-12-12 02:26:03.814 |
Run Code Online (Sandbox Code Playgroud)
这给了我这个输出:
| user_id | order_id | create_time_1 | create_time_2 |
|---------|----------|-------------------------|-------------------------|
| 1 | 5 | 2020-06-04 02:26:03.808 | 2021-01-01 02:26:03.821 |
Run Code Online (Sandbox Code Playgroud)
它有效,但现在我添加了另一个表:
dbo.orders_3
| user_id | order_id | create_time |
|---------|----------|-------------------------|
| 77 | 2 | 2015-09-15 02:26:03.808 |
| 3 | 4 | 2018-04-15 02:26:03.814 |
Run Code Online (Sandbox Code Playgroud)
我想找到这 3 个表中的任何重复项。我期望的是:
| user_id | order_id | create_time_1 | create_time_2 | create_time_3 |
|---------|----------|-------------------------|-------------------------|-------------------------|
| 1 | 5 | 2020-06-04 02:26:03.808 | 2021-01-01 02:26:03.821 | NULL |
| 3 | 4 | NULL | 2021-12-12 02:26:03.814 | 2018-04-15 02:26:03.814 |
Run Code Online (Sandbox Code Playgroud)
sql 应该是什么样的?这是我的在线游乐场:https://sqlize.online/sql/mssql2019/7f31a47ef4c633ad8b4ba88a4276964d/
通常,当在两个表中查找重复行时,我使用集合运算符INTERSECT,但这需要所有表都包含重复行。
要查找两个表的任意组合中的重复项,我将使用UNION ALL将所有行(包括重复行)放入单个表表达式中,然后查找它们。
然后您可以使用聚合来查找重复项,但您将丢失详细信息(create_time)。或者使用窗口函数来检测欺骗并保留细节。
; -- Previous statement must be properly terminated
WITH allTables
AS
(
SELECT 'orders_1' as src, * FROM dbo.orders_1 UNION ALL
SELECT 'orders_2' as src, * FROM dbo.orders_2 UNION ALL
SELECT 'orders_3' as src, * FROM dbo.orders_3
)
, detectDupes
AS
(
SELECT
*
, COUNT(1) OVER (PARTITION BY t.user_id, t.order_id) AS dupeCount
FROM allTables AS t
)
SELECT
*
FROM detectDupes
WHERE detectDupes.dupeCount > 1
ORDER BY
user_id
, order_id
, src
Run Code Online (Sandbox Code Playgroud)
这给了我这个输出
| 归档时间: |
|
| 查看次数: |
963 次 |
| 最近记录: |