2009-07-02 52 views
0

想象我在一个表中有这些列:如何删除参数因组而异,而不循环? (T-SQL)

id int NOT NULL IDENTITY PRIMARY KEY, 
instant datetime NOT NULL, 
foreignId bigint NOT NULL 

对于每一组(由foreignId分组)我想删除所有比最大(即时)年长1小时行。因此,对于每个组,参数都是不同的。

是否有可能没有循环?

回答

1
DELETE 
FROM mytable 
FROM mytable mto 
WHERE instant < 
     (
     SELECT DATEADD(hour, -1, MAX(instant)) 
     FROM mytable mti 
     WHERE mti.foreignid = mto.foreignid 
     ) 

注双FROM条款,这是有目的的,否则你将无法别名你从删除表。

的样本数据进行检查:

DECLARE @mytable TABLE 
     (
     id INT NOT NULL PRIMARY KEY, 
     instant DATETIME NOT NULL, 
     foreignID INT NOT NULL 
     ) 

INSERT 
INTO @mytable 
SELECT 1, '2009-22-07 10:00:00', 1 
UNION ALL 
SELECT 2, '2009-22-07 09:30:00', 1 
UNION ALL 
SELECT 3, '2009-22-07 08:00:00', 1 
UNION ALL 
SELECT 4, '2009-22-07 10:00:00', 2 
UNION ALL 
SELECT 5, '2009-22-07 08:00:00', 2 
UNION ALL 
SELECT 6, '2009-22-07 07:30:00', 2 

DELETE 
FROM @mytable 
FROM @mytable mto 
WHERE instant < 
     (
     SELECT DATEADD(hour, -1, MAX(instant)) 
     FROM @mytable mti 
     WHERE mti.foreignid = mto.foreignid 
     ) 

SELECT * 
FROM @mytable 

1 2009-07-22 10:00:00.000 1 
2 2009-07-22 09:30:00.000 1 
4 2009-07-22 10:00:00.000 2 
+0

我想了很久它工作,但不幸的是你的查询什么都不做。 – 2009-07-22 13:50:59

4

是的,这很简单。试试这个:

DELETE mt 
FROM MyTable AS mt 
WHERE mt.instant <= DATEADD(hh, -1, (SELECT MAX(instant) 
             FROM MyTable 
             WHERE ForeignID = mt.ForeignID)) 

或者这样:

;WITH MostRecentKeys 
AS 
(SELECT ForeignID, MAX(instant) AS LatestInstant 
FROM MyTable) 

DELETE mt 
FROM MyTable AS mt 
JOIN MostRecentKeys mrk ON mt.ForeignID = mrt.ForeignID 
     AND mt.Instant <= DATEADD(hh, -1, mrk.LatestInstant) 
0

我会假设当你说“比最大值(即时)年长1小时”你的意思是“比最大(即时)年长1小时为那个foreignId'。

鉴于这种情况,几乎可以肯定比这更简洁的方式,但它会工作:

DELETE 
    TableName 
WHERE 
    DATEADD(hh, 1, instant) < (SELECT MAX(instant) 
           FROM TableName T2 
           WHERE T2.foreignId = TableName.foreignId) 

内查询都称为“相关子查询”,如果你想寻找更多的信息。它的工作方式是对于外部查询所考虑的每一行,它是foreignId,行被子查询引用。