SQL - 使用 ID NOT IN 高级重复删除
SQL - Advanced duplicates removal using ID NOT IN
我在 table 中发现了重复项,需要将其删除。 table 包含:
- ID - table
的唯一键
- STUDENT_ID - 学生编号
- SUBJECT_ID - 学生的科目
- CLASS_ID - class 学生在
- XP_LVL - 专业水平
一个学生应该只有一个科目记录,class 和 XP_lvl。在这种情况下,重复项的删除基于全部删除但保留一个。
在我的例子中,重复项如下所示:
ID
STUDENT_ID
SUBJECT_ID
CLASS_ID
EXPERTISE_LVL
1
1AAA
55FFE
CLASS808
2
2
1AAA
55FFE
CLASS808
2
3
2AAB
49BB
CLASS890
3
4
2AAB
49BB
CLASS890
3
5
2AAB
49BB
CLASS890
4
6
2AAB
49BB
CLASS890
3
我已经通过创建 (CONCAT(STUDENT_ID, CONCAT(SUBJECT_ID, CLASS_ID)))
的唯一 ID,然后通过 having count.. >1
识别出所有重复项,效果很好。
现在我需要识别所有 ID,以便在从查询中删除时使用 ID NOT IN (SELECT...)
。
所以我这样做了..
AND ID NOT IN (SELECT UID FROM (
SELECT
min(ID) AS UID,
STUDENT_ID,
SUBJECT_ID,
CLASS_ID
FROM
my_table
GROUP BY
STUDENT_ID,
SUBJECT_ID,
CLASS_ID
HAVING
count(CONCAT(STUDENT_ID, CONCAT(SUBJECT_ID, CLASS_ID))) > 1))
但是我不能使用 min/max(ID)
来选择要保留的 ID,因为正如您所见,学生 2AAB 存在不同 XP_LVL.
的重复项
在这种情况下,我需要 select 最高的 ID XP_LVL 来保留并删除所有其他 ID。
我尝试使用 RANK、ROWNUM 不同的顺序和 subselects 的加载,但没有得到预期的结果。
有谁知道如何有效地做到这一点?我们正在谈论 6k 口是心非,所以我无法一一列举。
预先感谢您的帮助。
您可以使用 ROW_NUMBER
分析函数并使用 ROWID
伪列关联删除:
DELETE FROM my_table
WHERE ROWID IN (
SELECT ROWID
FROM (
SELECT ROW_NUMBER() OVER (
PARTITION BY student_id, subject_id, class_id
ORDER BY expertise_lvl DESC
) AS rn
FROM my_table
)
WHERE rn > 1
)
db<>fiddle here
我在 table 中发现了重复项,需要将其删除。 table 包含:
- ID - table 的唯一键
- STUDENT_ID - 学生编号
- SUBJECT_ID - 学生的科目
- CLASS_ID - class 学生在
- XP_LVL - 专业水平
一个学生应该只有一个科目记录,class 和 XP_lvl。在这种情况下,重复项的删除基于全部删除但保留一个。
在我的例子中,重复项如下所示:
ID | STUDENT_ID | SUBJECT_ID | CLASS_ID | EXPERTISE_LVL |
---|---|---|---|---|
1 | 1AAA | 55FFE | CLASS808 | 2 |
2 | 1AAA | 55FFE | CLASS808 | 2 |
3 | 2AAB | 49BB | CLASS890 | 3 |
4 | 2AAB | 49BB | CLASS890 | 3 |
5 | 2AAB | 49BB | CLASS890 | 4 |
6 | 2AAB | 49BB | CLASS890 | 3 |
我已经通过创建 (CONCAT(STUDENT_ID, CONCAT(SUBJECT_ID, CLASS_ID)))
的唯一 ID,然后通过 having count.. >1
识别出所有重复项,效果很好。
现在我需要识别所有 ID,以便在从查询中删除时使用 ID NOT IN (SELECT...)
。
所以我这样做了..
AND ID NOT IN (SELECT UID FROM (
SELECT
min(ID) AS UID,
STUDENT_ID,
SUBJECT_ID,
CLASS_ID
FROM
my_table
GROUP BY
STUDENT_ID,
SUBJECT_ID,
CLASS_ID
HAVING
count(CONCAT(STUDENT_ID, CONCAT(SUBJECT_ID, CLASS_ID))) > 1))
但是我不能使用 min/max(ID)
来选择要保留的 ID,因为正如您所见,学生 2AAB 存在不同 XP_LVL.
在这种情况下,我需要 select 最高的 ID XP_LVL 来保留并删除所有其他 ID。
我尝试使用 RANK、ROWNUM 不同的顺序和 subselects 的加载,但没有得到预期的结果。
有谁知道如何有效地做到这一点?我们正在谈论 6k 口是心非,所以我无法一一列举。 预先感谢您的帮助。
您可以使用 ROW_NUMBER
分析函数并使用 ROWID
伪列关联删除:
DELETE FROM my_table
WHERE ROWID IN (
SELECT ROWID
FROM (
SELECT ROW_NUMBER() OVER (
PARTITION BY student_id, subject_id, class_id
ORDER BY expertise_lvl DESC
) AS rn
FROM my_table
)
WHERE rn > 1
)
db<>fiddle here