如何使用较旧的日期字段删除SQL中的重复行

时间:2015-09-24 17:36:19

标签: database oracle stored-procedures

我的表中有两行是完全重复的,但日期字段除外。我希望找到这些记录,并希望通过比较日期来删除旧记录。

例如,我有以下数据

    ctrc_num | Ctrc_name   | some_date
   ---------------------------------------
        12345 | John R      | 2011-01-12
        12345 | John R      | 2012-01-12
        56789 | Sam S       | 2011-01-12
        56789 | Sam S       | 2012-01-12

现在的想法是找到具有不同“some_date”字段的重复项并删除旧记录。最终输出看起来应该是这样的。

      ctrc_num | Ctrc_name   | some_date
   ---------------------------------------
        12345 | John R      | 2012-01-12
        56789 | Sam S       | 2012-01-12

另请注意,我的表没有主键,它最初是以这种方式创建的,不确定原因,并且必须适合存储过程。

2 个答案:

答案 0 :(得分:0)

这适用于SQL Server

CREATE TABLE StackOverFlow
    ([ctrc_num] int, [Ctrc_name] varchar(6), [some_date] datetime)
;

INSERT INTO StackOverFlow
    ([ctrc_num], [Ctrc_name], [some_date])
SELECT 12345, 'John R', '2011-01-12 00:00:00' UNION ALL
SELECT 12345, 'John R', '2012-01-12 00:00:00' UNION ALL
SELECT 56789, 'Sam S', '2011-01-12 00:00:00' UNION ALL
SELECT 56789, 'Sam S', '2012-01-12 00:00:00'

;WITH RankedByDate AS
(
SELECT ctrc_num
,Ctrc_name
,some_date
,ROW_NUMBER() OVER(PARTITION BY Ctrc_num, Ctrc_name ORDER BY some_date DESC) AS rNum
FROM StackOverFlow
)
DELETE
FROM RankedByDate
WHERE rNum > 1

SELECT
[ctrc_num]
, [Ctrc_name]
, [some_date]
FROM StackOverFlow

这是sql小提琴测试它http://sqlfiddle.com/#!6/32718/6

我在这里尝试做的是

  1. 按日期降序排列记录
  2. 删除较旧的(保留最新版本)

答案 1 :(得分:0)

如果你看一下:

SELECT * FROM <tablename> WHERE some_date IN
(
SELECT MAX(some_date) FROM <tablename> GROUP BY ctrc_num,ctrc_name
HAVING COUNT(ctrc_num) > 1 
AND COUNT(ctrc_name) > 1
)

您可以看到它为重复行选择了两个最近的日期。如果我将括号中的选项切换到最小日期&#39;并使用它删除然后删除重复行的两个较旧日期。

DELETE FROM <tablename> WHERE some_date IN
(
SELECT MIN(some_date) FROM <tablename> GROUP BY ctrc_num,ctrc_name
HAVING COUNT(ctrc_num) > 1 
AND COUNT(ctrc_name) > 1
)