陷入了有选择DELETE语句在一个表中的T-SQL(Got mired in a selective

2019-09-19 23:28发布

再说了,我有这样的(SQL Server 2008中)的表:

CREATE TABLE tbl (ID INT, dtIn DATETIME2, dtOut DATETIME2, Type INT)

INSERT tbl VALUES
(1, '05:00', '6:00', 1),  -- will be removed
(2, '05:00', '7:00', 1),  -- will be removed
(3, '05:01', '8:00', 1),
(4, '05:00', '8:00', 1),
(5, '05:00', '6:00', 2),  -- will be removed
(6, '05:00', '7:00', 2),
(7, '05:00', '7:00', 3),
(8, '04:00', '7:00', 3)

我需要用相同的“dtIn”去掉相同的“类型”的所有记录(如果两个以上的),选择自己的“型”,除了具有最大“dtOut”。 换句话说,上面的表格应该导致这样的:

(3, '05:01', '8:00', 1),   -- no matching 'dtIn' for 'type' = 1
(4, '05:00', '8:00', 1),   -- largest 'dtOut' for 'type' = 1
(6, '05:00', '7:00', 2),   -- largest 'dtOut' for 'type' = 2
(7, '05:00', '7:00', 3),   -- no matching 'dtIn' for 'type' = 3
(8, '04:00', '7:00', 3)    -- no matching 'dtIn' for 'type' = 4

你怎么连与同等类型从同一个表中选择多行。 你不能从TBL做选择*其中type =类型....无论如何,我会很感激一些帮助,这...

Answer 1:

下面就来选择要删除的行的一种方式:

SELECT *
FROM tbl T1
WHERE EXISTS
(
    SELECT *
    FROM tbl T2
    WHERE T1.Type = T2.Type
    AND T1.dtIn = T2.dtIn
    AND (
            T1.dtOut < T2.dtOut
            OR (T1.dtOut = T2.dtOut AND T1.id < T2.id)
        )
)

该查询也可以很容易地改变实际删除行。 只要改变SELECT *DELETE T1 。 但是请不要测试它,你实际运行delete语句之前想要的东西。

看到它的在线工作: sqlfiddle


更新

下面是使用ROW_NUMBER的方法:

;WITH T1 AS (
    SELECT id, ROW_NUMBER() OVER (PARTITION BY Type, dtIn
                                  ORDER BY dtOut DESC, ID DESC) AS rn
    FROM tbl
)
SELECT * FROM tbl
WHERE id IN
(
    SELECT id
    FROM T1
    WHERE rn > 1
)

看到它的在线工作: sqlfiddle



Answer 2:

不是很优雅(+的条件是相同的马克的答案),但它是一个另类。

小提琴是这里

;with my_cte(ID)
as
(
  SELECT T1.ID
  FROM 
      tbl T1
      JOIN tbl T2 on
        T1.Type = T2.Type
        AND T1.dtIn = T2.dtIn
        AND T1.dtOut < T2.dtOut
  )
select *
from tbl t
where not exists 
              (
              select 1 
              from my_cte c 
              where t.ID = c.ID
              ) 


Answer 3:

查询的重复的行

我刚才看到你可以有重复的行。 所以:

DELETE X
FROM
   (SELECT Row_Number() OVER (PARTITION BY Type, dtIn ORDER BY dtOut DESC) Item, *
   FROM #tbl) X
WHERE Item > 1

需要注意的是这个版本以上不需要加入让应比其他所有的查询页面上有更好的表现。

要么

DELETE T
FROM #tbl T
   CROSS APPLY (
      SELECT TOP 1 *
      FROM #tbl T2
      WHERE
         T.dtIn = T2.dtIn
         AND T.Type = T2.Type
      ORDER BY T2.dtOut DESC, T2.ID DESC
   ) X
WHERE T.ID < X.ID

要么

DELETE T
FROM #tbl T
   INNER JOIN #tbl T2
      ON T.dtIn = T2.dtIn
      AND T.Type = T2.Type
      AND (
         T.dtOut < T2.dtOut
         OR (T.tdOut = T2.dtOut AND T.ID > T2.ID)
      )

查询为不重复的行

如果你不能有重复的行(除ID),那么这将是简单的:

DELETE T
FROM #tbl T
WHERE EXISTS (
   SELECT * FROM #tbl T2
   WHERE
      T.dtIn = T2.dtIn
      AND T.Type = T2.Type
      AND T.dtOut < T2.dtOut
)

甚至

DELETE T
FROM #tbl T
   INNER JOIN #tbl T2
      ON T.dtIn = T2.dtIn
      AND T.Type = T2.Type
      AND T.dtOut < T2.dtOut


Answer 4:

我的是从@马克的有点不同,但我相信它应该让你相同的结果(只是因为我认为id是唯一的):

DELETE a
FROM dbo.tbl a
WHERE id <> (
    SELECT MAX(id)
    from dbo.tbl b
    WHERE a.type = b.type
      AND a.dtIn = b.dtIn
)


Answer 5:

DECLARE @Table TABLE     
(  
ID INT,  
newno int  
)   

insert @table  
SELECT T1.ID,   
ROW_NUMBER() OVER (PARTITION BY Type, dtIn
                              ORDER BY dtOut DESC, ID DESC) AS newno  
 FROM tbl T1      

 select *  
from tbl t
where t.ID IN
             (
              select ID from @Table where newno > 1
              )    


文章来源: Got mired in a selective DELETE statement on a single table in t-SQL