使用PostgreSQL在select查询中删除基于字段的重复行?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PostgreSQL在select查询中删除基于字段的重复行?相关的知识,希望对你有一定的参考价值。
考虑包含以下字段的表mdl_files
:id
,contenthash
,timecreated
,filesize
。
此表存储附件文件。
我们认为具有相同内容哈希的所有行都是重复行,我只想保留最旧的行(或者如果日期等于则首先保留)。我怎样才能做到这一点?
以下查询:
SELECT
id,
contenthash,
filesize,
to_timestamp(timecreated) :: DATE
FROM mdl_files
ORDER BY contenthash;
收益:
2480229 00002e87605311feb82b70473b61e81f0223c774 18178 2016-10-05
2997411 0000bfd20ef84948eee6811ce5bbac03de42ccb0 1293 2017-03-31
1304839 000280169fc78d704a2d4569bfb6f42ea4a1d5ae 8203 2015-11-10
1364656 000280169fc78d704a2d4569bfb6f42ea4a1d5ae 8203 2015-11-17
71568 0003c6aec5835964870902d697c06d21abf76bf7 139439 2013-04-19
2959945 000419c19d77df7285e669614075b47414e3ab2c 398 2017-03-20
3483049 00061dc0bc2452304107ddc75e7ee2908c729905 28618 2017-08-17
3483047 00061dc0bc2452304107ddc75e7ee2908c729905 28618 2017-08-17
我想得到这个结果集:
2480229 00002e87605311feb82b70473b61e81f0223c774 18178 2016-10-05
2997411 0000bfd20ef84948eee6811ce5bbac03de42ccb0 1293 2017-03-31
1304839 000280169fc78d704a2d4569bfb6f42ea4a1d5ae 8203 2015-11-10
71568 0003c6aec5835964870902d697c06d21abf76bf7 139439 2013-04-19
2959945 000419c19d77df7285e669614075b47414e3ab2c 398 2017-03-20
3483049 00061dc0bc2452304107ddc75e7ee2908c729905 28618 2017-08-17
我希望从结果集中删除以下重复行:
1364656 000280169fc78d704a2d4569bfb6f42ea4a1d5ae 8203 2015-11-17
3483047 00061dc0bc2452304107ddc75e7ee2908c729905 28618 2017-08-17
答案
使用DISTINCT ON
:
SELECT DISTINCT ON (contenthash)
id,
contenthash,
filesize,
to_timestamp(timecreated) :: DATE
FROM mdl_files
ORDER BY contenthash, timecreated, id;
DISTINCT ON
是一个Postgres扩展,它确保为括号中每个唯一的键组合返回一行。特定行是基于order by
子句找到的第一行。
另一答案
您可以尝试使用带有Windows功能的ROW_NUMBER()
来创建行号然后将其删除。
SELECT t.*
FROM (
SELECT
id,
contenthash,
filesize,
ROW_NUMBER() OVER (PARTITION BY contenthash,filesize order by timecreated) rn
FROM mdl_files
) t
where t.rn = 1
如果你想要DELETE
重复数据,你可以在where子句中使用EXISTS
。
DELETE
FROM mdl_files f WHERE EXISTS(
SELECT 1
FROM (
SELECT
id,
contenthash,
filesize,
ROW_NUMBER() OVER (PARTITION BY contenthash,filesize order by timecreated) rn
FROM mdl_files
) t
where t.rn > 1 and t.id = f.id
)
以上是关于使用PostgreSQL在select查询中删除基于字段的重复行?的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL——查询重写——删除重写规则以及对查询树进行重写
PostgreSQL——查询重写——删除重写规则以及对查询树进行重写