删除与前一个SQL Server类似的记录

时间:2014-02-22 16:04:53

标签: sql sql-server

我正在寻找一个查询,它会提取与前一行相比不同的数据

示例代码(包含表创建和数据)

create table #temp 
(id int, eid int, name char(10),estid int, ecid int, epid int, etc char(5)  )

insert into #temp values (1,1,'a',1,1,1,'a')
insert into #temp values (2,1,'a',1,1,1,'a')
insert into #temp values (3,1,'a',2,1,1,'a')
insert into #temp values (4,1,'a',1,1,1,'a')
insert into #temp values (5,1,'a',1,1,1,'a')
insert into #temp values (6,1,'a',1,2,1,'a')
insert into #temp values (7,1,'a',1,1,1,'a')
insert into #temp values (8,1,'a',2,1,1,'a')
insert into #temp values (9,1,'a',1,1,1,'a')
insert into #temp values (10,1,'a',1,1,1,'a')
insert into #temp values (11,2,'a',1,1,1,'a')
insert into #temp values (12,2,'a',1,1,1,'a')
insert into #temp values (13,2,'a',2,1,1,'a')
insert into #temp values (14,2,'a',1,1,1,'a')
insert into #temp values (15,2,'a',1,1,1,'a')
insert into #temp values (16,2,'a',1,2,1,'a')
insert into #temp values (17,2,'a',1,1,1,'a')
insert into #temp values (18,2,'a',2,1,1,'a')
insert into #temp values (19,2,'a',1,1,1,'a')
insert into #temp values (20,2,'a',1,1,1,'a')

我尝试了一些以我预期的方式获取数据的方法

SELECT * INTo #Temp_Final
FROM  #temp
WHERE #temp.%%physloc%%
      NOT IN (SELECT Min(b.%%physloc%%)
              FROM   #temp b
              GROUP BY eid,name,estid,ecid,epid,etc)
         ORDER BY id

SELECT * FROM #temp WHERE id not in (SELECT id FROM #Temp_Final) ORDER BY id

但我没有像我预期的那样得到结果......

这是结果需要的方式

select * from #temp where id in (1,3,4,6,7,8,9,11,13,14,16,17,18,19)

3 个答案:

答案 0 :(得分:0)

对于SQL Server 2012(SQL Fiddle

WITH CTE
     AS (SELECT *,
                LAG(eid) OVER (ORDER BY id)   AS prev_eid,
                LAG(name) OVER (ORDER BY id)  AS prev_name,
                LAG(estid) OVER (ORDER BY id) AS prev_estid,
                LAG(ecid) OVER (ORDER BY id)  AS prev_ecid,
                LAG(epid) OVER (ORDER BY id)  AS prev_epid,
                LAG(etc) OVER (ORDER BY id)   AS prev_etc
         FROM   #temp)
DELETE FROM CTE
WHERE  EXISTS (SELECT eid,
                      name,
                      estid,
                      ecid,
                      epid,
                      etc
               INTERSECT
               SELECT prev_eid,
                      prev_name,
                      prev_estid,
                      prev_ecid,
                      prev_epid,
                      prev_etc) 

答案 1 :(得分:0)

您可以通过简单的自我加入和适当的比较来实现这一目标:

select t.*
from #temp t left outer join
     #temp tprev
     on t.id = tprev.id + 1
where tprev.id is null or
      t.name <> tprev.name or
      t.estid <> tprev.estid or
      t.ecid <> tprev.ecid or
      t.epid <> tprev.epid or
      t.etc <> tprev.etc;

这假设id是顺序的,没有间隙。如果不是id,则可以使用相关子查询或lag()函数获取先前的id。

你的标题是“删除”,但问题似乎只是想要这些行的列表。如果需要,您可以将其标记为delete查询。

答案 2 :(得分:0)

 select
    t.id,
    t.eid,
    t.name,
    t.estid,
    t.ecid,
    t.epid,
    t.etc
from #temp t
    left join #temp d
        on  d.id = t.id-1
        and d.eid = t.eid
        and d.name = t.name
        and d.estid = t.estid
        and d.ecid = t.ecid
        and d.epid = t.epid
        and d.etc = t.etc
where d.id is null