屏幕截图显示了表格的前8行。对于相同的id(每个id有数千行),基于相同的" updatetime",我只想保留第一行,删除其余行。例如,我想删除第3行,第5行,第8行。两行的所有列可能完全相同(这里当updatetime相同时,UpdateMillisec是不同的,但不是必需的)。截图是查询的结果,我现在没有主键(截屏中最左边的列现在不在表中)。我应该写什么SQL代码?提前谢谢!
答案 0 :(得分:3)
有一种简单的方法可以删除重复的行。
在第一步中,我们将对记录进行排序并添加一个rownumber 第二步将删除rownumber>的行。 1。
WITH CTE AS
(
SELECT *
,ROW_NUMBER() OVER
(PARTITION BY id, updatetime
ORDER BY id, updatetime, UpdateMillisec ASC
) AS RowNum
FROM yourtable
)
SELECT * FROM CTE -- for checking the result before deleting
-- DELETE FROM CTE WHERE RowNum > 1 -- uncomment this row for the final DELETE
注意:
要识别,哪个是第一个记录,哪个是后续(第二个,第三个......)记录,我们必须对数据进行排序。
在删除它们之前,请始终使用SELECT * FROM CTE
第一个
在您的情况下,我检查了上述查询的结果集,即:
id lastprice updatetime UpdateMillisec RowNum
211709 51370 09:30:00.0000000 500 1
211709 51380 09:30:01.0000000 0 1
211709 51370 09:30:01.0000000 500 2
211709 51370 09:30:02.0000000 0 1
211709 51370 09:30:02.0000000 500 2
211709 51370 09:30:03.0000000 0 1
211709 51370 09:30:04.0000000 0 1
211709 51370 09:30:04.0000000 500 2
正如我们所看到的,确切地说,您要删除的那些记录的RowNum = 2.所以最后我们可以将SELECT *
更改为DELETE
并再次执行查询。
答案 1 :(得分:0)
提供按列分区的行号,然后按time
列排序,然后删除不需要的行。
<强>查询强>
;with cte as(
select [rn] = row_number() over(
partition by [id], [lastprice], [updatetime]
order by [id], [updatetime], [updateMillisec]
), *
from [your_table_nam]
)
select * from cte -- first select and check whether these are the rows that has to be deleted
where [rn] > 1;
如果没问题,请删除[rn]
大于1
的行。
delete from cte
where [rn] > 1;
答案 2 :(得分:0)
我喜欢@Estban P。的解决方案。我很想进一步尝试。事实证明也可以这样做:
DELETE seq FROM (SELECT ROW_NUMBER()
OVER(PARTITION BY id, updatetime ORDER BY id, updatetime, updatems ASC) AS RowNum
FROM tbl ) seq where rownum>1;
所以,您甚至不必使用CTE,请参阅此处的演示http://rextester.com/VLZOD12591