TSQL:根据最大值(日期)删除重复项
我正在搜索一个查询,以选择最长日期(一个TSQL:根据最大值(日期)删除重复项,tsql,sql-server-2000,Tsql,Sql Server 2000,我正在搜索一个查询,以选择最长日期(一个datetime列),并保留其id和row\u id。需要删除源表中的行 源数据 id date row_id(unique) 1 11/11/2009 1 1 12/11/2009 2 1 13/11/2009 3 2 1/11/2009 4 预期幸存者 1 13/11/2009 3 2 1/11/2009 4 我需要什么查询才
datetime
列),并保留其id
和row\u id
。需要删除源表中的行
源数据
id date row_id(unique)
1 11/11/2009 1
1 12/11/2009 2
1 13/11/2009 3
2 1/11/2009 4
预期幸存者
1 13/11/2009 3
2 1/11/2009 4
我需要什么查询才能获得我想要的结果?在PostgreSQL上测试:
delete from table where (id, date) not in (select id, max(date) from table group by id);
在PostgreSQL上测试:
delete from table where (id, date) not in (select id, max(date) from table group by id);
有多种方法可以做到这一点,但基本思想是相同的:
-标识要保留的行
-将表中的每一行与要保留的行进行比较
-删除任何不匹配的内容
有多种方法可以做到这一点,但基本思想是相同的:
-标识要保留的行
-将表中的每一行与要保留的行进行比较
-删除任何不匹配的内容
因为您使用的是SQLServer2000,所以无法使用设置序列的行覆盖技术,也无法为每个唯一id标识最上面的行 因此,您建议的技术是使用datetime列获取前1行以删除重复项。这可能行得通,但仍有可能得到具有相同datetime值的副本。但这很容易检查 首先检查基于id和日期列的所有行都是唯一的假设:
CREATE TABLE #TestTable (rowid INT IDENTITY(1,1), thisid INT, thisdate DATETIME)
INSERT INTO #TestTable (thisid,thisdate) VALUES (1, '11/11/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (1, '12/11/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (1, '12/12/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (2, '1/11/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (2, '1/11/2009')
SELECT COUNT(*) AS thiscount
FROM #TestTable
GROUP BY thisid, thisdate
HAVING COUNT(*) > 1
此示例返回的值为2-表示即使在使用“日期”列删除重复项之后,仍然会得到重复项。如果您返回0,那么您已经证明了所建议的技术可以工作
在对生产数据进行重复数据消除时,我认为应该采取一些预防措施,并在前后进行测试。您应该创建一个表来保存计划删除的行,以便在执行delete语句后,如果需要,可以轻松地恢复它们
另外,最好事先知道要删除多少行,以便在删除前后验证计数,并测量删除操作的大小。根据受影响的行数,您可以计划何时运行该操作
要在重复数据消除过程之前进行测试,请查找出现的情况
-- Get occurrences of duplicates
SELECT COUNT(*) AS thiscount
FROM
#TestTable
GROUP BY thisid
HAVING COUNT(*) > 1
ORDER BY thisid
这将为您提供具有多个相同id行的行。将此查询中的行捕获到临时表中,然后使用总和运行查询,以根据您的键获取不唯一的行总数
要获取计划删除的行数,需要基于唯一键的重复行数,以及基于唯一键的不同行数。从出现次数中减去不同的行。所有这些都非常简单-所以我将留给您去做。因为您使用的是SQL Server 2000,所以您无法使用设置序列的逐行扫描技术,也无法为每个唯一id标识最上面的一行 因此,您建议的技术是使用datetime列获取前1行以删除重复项。这可能行得通,但仍有可能得到具有相同datetime值的副本。但这很容易检查 首先检查基于id和日期列的所有行都是唯一的假设:
CREATE TABLE #TestTable (rowid INT IDENTITY(1,1), thisid INT, thisdate DATETIME)
INSERT INTO #TestTable (thisid,thisdate) VALUES (1, '11/11/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (1, '12/11/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (1, '12/12/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (2, '1/11/2009')
INSERT INTO #TestTable (thisid,thisdate) VALUES (2, '1/11/2009')
SELECT COUNT(*) AS thiscount
FROM #TestTable
GROUP BY thisid, thisdate
HAVING COUNT(*) > 1
此示例返回的值为2-表示即使在使用“日期”列删除重复项之后,仍然会得到重复项。如果您返回0,那么您已经证明了所建议的技术可以工作
在对生产数据进行重复数据消除时,我认为应该采取一些预防措施,并在前后进行测试。您应该创建一个表来保存计划删除的行,以便在执行delete语句后,如果需要,可以轻松地恢复它们
另外,最好事先知道要删除多少行,以便在删除前后验证计数,并测量删除操作的大小。根据受影响的行数,您可以计划何时运行该操作
要在重复数据消除过程之前进行测试,请查找出现的情况
-- Get occurrences of duplicates
SELECT COUNT(*) AS thiscount
FROM
#TestTable
GROUP BY thisid
HAVING COUNT(*) > 1
ORDER BY thisid
这将为您提供具有多个相同id行的行。将此查询中的行捕获到临时表中,然后使用总和运行查询,以根据您的键获取不唯一的行总数
要获取计划删除的行数,需要基于唯一键的重复行数,以及基于唯一键的不同行数。从出现次数中减去不同的行。所有这些都很简单,所以我就让你去做吧。试试这个
declare @t table (id int, dt DATETIME,rowid INT IDENTITY(1,1))
INSERT INTO @t (id,dt) VALUES (1, '11/11/2009')
INSERT INTO @t (id,dt) VALUES (1, '11/12/2009')
INSERT INTO @t (id,dt) VALUES (1, '11/13/2009')
INSERT INTO @t (id,dt) VALUES (2, '11/01/2009')
查询:
delete from @t where rowid not in(
select t.rowid from @t t
inner join(
select MAX(dt)maxdate
from @t
group by id) X
on t.dt = X.maxdate )
select * from @t
输出:
id dt rowid
1 2009-11-13 00:00:00.000 3
2 2009-11-01 00:00:00.000 4
试试这个
declare @t table (id int, dt DATETIME,rowid INT IDENTITY(1,1))
INSERT INTO @t (id,dt) VALUES (1, '11/11/2009')
INSERT INTO @t (id,dt) VALUES (1, '11/12/2009')
INSERT INTO @t (id,dt) VALUES (1, '11/13/2009')
INSERT INTO @t (id,dt) VALUES (2, '11/01/2009')
查询:
delete from @t where rowid not in(
select t.rowid from @t t
inner join(
select MAX(dt)maxdate
from @t
group by id) X
on t.dt = X.maxdate )
select * from @t
输出:
id dt rowid
1 2009-11-13 00:00:00.000 3
2 2009-11-01 00:00:00.000 4
我已经验证了这个答案
INSERT INTO #t (id,dt) VALUES (1, '11/11/2009')
INSERT INTO #t (id,dt) VALUES (1, '11/12/2009')
INSERT INTO #t (id,dt) VALUES (1, '11/13/2009')
INSERT INTO #t (id,dt) VALUES (2, '11/01/2009')
select * from #t
;WITH T AS(
select dense_rank() over(partition by id order by dt desc)NO,DT,ID,rowid from #t )
DELETE T WHERE NO>1
我已经测试了这个答案。你说删除重复项,但显然你正在删除最小值和最大值之间的所有日期-你能澄清一下吗?你说删除重复项,但是显然您正在删除最小值和最大值之间的所有日期-您能澄清一下吗?公用表表达式在SQL Server 2000中不起作用公用表表达式在SQL Server 2000中不起作用
INSERT INTO #t (id,dt) VALUES (1, '11/11/2009')
INSERT INTO #t (id,dt) VALUES (1, '11/12/2009')
INSERT INTO #t (id,dt) VALUES (1, '11/13/2009')
INSERT INTO #t (id,dt) VALUES (2, '11/01/2009')
select * from #t
;WITH T AS(
select dense_rank() over(partition by id order by dt desc)NO,DT,ID,rowid from #t )
DELETE T WHERE NO>1