再说了,我有这样的(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 =类型....无论如何,我会很感激一些帮助,这...
下面就来选择要删除的行的一种方式:
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
不是很优雅(+的条件是相同的马克的答案),但它是一个另类。
小提琴是这里
;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
)
查询的重复的行
我刚才看到你可以有重复的行。 所以:
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
我的是从@马克的有点不同,但我相信它应该让你相同的结果(只是因为我认为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
)
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
)