比较 SQL 中的列时如何打破平局
How to break ties when comparing columns in SQL
我正在尝试删除 Postgres 中的重复项。我将其用作查询的基础:
DELETE FROM case_file as p
WHERE EXISTS (
SELECT FROM case_file as p1
WHERE p1.serial_no = p.serial_no
AND p1.cfh_status_dt < p.cfh_status_dt
);
它运行良好,除了当日期 cfh_status_dt
相等时,不会删除任何记录。
对于具有相同 serial_no 且日期相同的行,我想保留具有 registration_no 的行(如果有的话,此列也有 NULLS)。
有没有一种方法可以对所有一个查询执行此操作,可能使用 case 语句或其他简单比较?
DELETE FROM case_file AS p
WHERE id NOT IN (
SELECT DISTINCT ON (serial_no) id -- id = PK
FROM case_file
ORDER BY serial_no, cfh_status_dt DESC, registration_no
);
这会保留每个 serial_no
的(一个)最新行,如果有多个候选者,则选择最小的 registration_no
。
NULL
按默认升序最后排序。因此,任何具有非空 registration_no
的行都是首选。
如果您想要 greatest registration_no
,仍然对 NULL 值 last 进行排序,请使用:
...
ORDER BY serial_no, cfh_status_dt DESC, registration_no DESC NULLS LAST
参见:
- Select first row in each GROUP BY group?
- Sort by column ASC, but NULL values first?
如果您没有 PK (PRIMARY KEY
) 或其他 UNIQUE NOT NULL
(组合)列可用于此目的,您可以回退到 ctid
。参见:
- How do I (or can I) SELECT DISTINCT on multiple columns?
NOT IN
通常不是最有效的方法。但这处理涉及 NULL 值的重复项。参见:
- How to delete duplicate rows without unique identifier
如果有很多重复项 - 你可以负担得起! - 创建一个新的、原始的 table 幸存者并替换旧的 table,而不是删除现有 table.[= 中的大部分行,效率会(高得多) 27=]
或者创建一个临时 table 幸存者,截断旧的并从临时 table 插入。通过这种方式,依赖对象(如视图或 FK 约束)可以保留在原地。参见:
- How to delete duplicate entries?
幸存行只是:
SELECT DISTINCT ON (serial_no) *
FROM case_file
ORDER BY serial_no, cfh_status_dt DESC, registration_no;
我正在尝试删除 Postgres 中的重复项。我将其用作查询的基础:
DELETE FROM case_file as p
WHERE EXISTS (
SELECT FROM case_file as p1
WHERE p1.serial_no = p.serial_no
AND p1.cfh_status_dt < p.cfh_status_dt
);
它运行良好,除了当日期 cfh_status_dt
相等时,不会删除任何记录。
对于具有相同 serial_no 且日期相同的行,我想保留具有 registration_no 的行(如果有的话,此列也有 NULLS)。
有没有一种方法可以对所有一个查询执行此操作,可能使用 case 语句或其他简单比较?
DELETE FROM case_file AS p
WHERE id NOT IN (
SELECT DISTINCT ON (serial_no) id -- id = PK
FROM case_file
ORDER BY serial_no, cfh_status_dt DESC, registration_no
);
这会保留每个 serial_no
的(一个)最新行,如果有多个候选者,则选择最小的 registration_no
。
NULL
按默认升序最后排序。因此,任何具有非空 registration_no
的行都是首选。
如果您想要 greatest registration_no
,仍然对 NULL 值 last 进行排序,请使用:
...
ORDER BY serial_no, cfh_status_dt DESC, registration_no DESC NULLS LAST
参见:
- Select first row in each GROUP BY group?
- Sort by column ASC, but NULL values first?
如果您没有 PK (PRIMARY KEY
) 或其他 UNIQUE NOT NULL
(组合)列可用于此目的,您可以回退到 ctid
。参见:
- How do I (or can I) SELECT DISTINCT on multiple columns?
NOT IN
通常不是最有效的方法。但这处理涉及 NULL 值的重复项。参见:
- How to delete duplicate rows without unique identifier
如果有很多重复项 - 你可以负担得起! - 创建一个新的、原始的 table 幸存者并替换旧的 table,而不是删除现有 table.[= 中的大部分行,效率会(高得多) 27=]
或者创建一个临时 table 幸存者,截断旧的并从临时 table 插入。通过这种方式,依赖对象(如视图或 FK 约束)可以保留在原地。参见:
- How to delete duplicate entries?
幸存行只是:
SELECT DISTINCT ON (serial_no) *
FROM case_file
ORDER BY serial_no, cfh_status_dt DESC, registration_no;