You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无索引或ID的PostgreSQL stock表删除datetime重复行的方法

PostgreSQL 删除stock表中datetime重复的行

场景说明

使用PostgreSQL,现有stock表无主键或索引,字段包含open、high、low、close、volume、datetime,表中存在datetime字段重复的行,需删除重复行,每个datetime仅保留一行。

原表数据

openhighlowclosevolumedatetime
383.97384.22383.66384.0812986492022-12-16 14:25:00
383.59384.065383.45383.989913272022-12-16 14:20:00
383.59384.065383.45383.989913272022-12-16 14:20:00
383.59384.065383.45383.989913272022-12-16 14:20:00
383.64384.2099383.54383.6114392712022-12-16 14:15:00

期望输出

openhighlowclosevolumedatetime
383.97384.22383.66384.0812986492022-12-16 14:25:00
383.59384.065383.45383.989913272022-12-16 14:20:00
383.64384.2099383.54383.6114392712022-12-16 14:15:00

正确SQL写法

方法1:直接删除重复行(适合不重建表的场景)

利用窗口函数标记重复行,删除编号大于1的重复记录:

WITH ranked_stock AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY datetime ORDER BY (SELECT NULL)) AS rn
    FROM stock
)
DELETE FROM stock
USING ranked_stock
WHERE stock.open = ranked_stock.open
  AND stock.high = ranked_stock.high
  AND stock.low = ranked_stock.low
  AND stock.close = ranked_stock.close
  AND stock.volume = ranked_stock.volume
  AND stock.datetime = ranked_stock.datetime
  AND ranked_stock.rn > 1;

说明:因为表无主键,需要通过所有字段匹配定位行;PARTITION BY datetime按时间分组,ROW_NUMBER()给每组内的行编号,编号>1的即为重复行。

方法2:重建去重表(适合重复行字段完全一致的场景)

如果重复行的所有字段值都相同(如示例数据),可以直接创建去重后的新表替换原表,效率更高:

-- 创建去重后的临时表
CREATE TABLE stock_temp AS
SELECT DISTINCT ON (datetime) *
FROM stock
ORDER BY datetime, (SELECT NULL); -- 第二个排序字段仅满足语法要求,不影响结果

-- 删除原表
DROP TABLE stock;

-- 重命名临时表为原表名
ALTER TABLE stock_temp RENAME TO stock;

说明:DISTINCT ON (datetime)会保留每个datetime对应的第一行,由于重复行字段完全一致,保留任意一行均可。

注意事项

  • 操作前请务必备份数据,避免误删;
  • 若后续需避免重复数据,建议给datetime字段添加唯一约束:ALTER TABLE stock ADD CONSTRAINT unique_datetime UNIQUE (datetime);

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:45:33