通过连接到符合某些条件的另一个表的最新记录来更新表?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (48)

我试图避免使用此解决方案的循环的冲动,而是使用基于集合的操作。

我需要根据最近发生的连接更新表中的每条记录到另一个表。我的第一个想法是加入到表中,我需要来自和来自加入条件的“最近的日期”,但使用GROUP BYUPDATE无效。

这是迄今为止我所拥有的。

CREATE TABLE Part (
    Area            VARCHAR(10) NOT NULL,
    SequenceNumber  INT         NOT NULL,
    DateAdded       DATETIME    NOT NULL
);
INSERT INTO Part VALUES
('A', 1, '2018-04-01'),
('A', 1, '2018-04-02'),
('A', 2, '2018-04-03'),
('A', 2, '2018-04-04'),
('B', 2, '2018-04-04'),
('B', 2, '2018-04-03'),
('B', 3, '2018-04-02'),
('B', 3, '2018-04-01');

DECLARE @Filters    TABLE
(
    Area            VARCHAR(10),
    StartingSeqNum  INT,
    StartTime       DATETIME 
);
INSERT INTO @Filters VALUES
('A', 2, NULL),
('B', 3, NULL);

-- Update each StartTime in @Filters with the most recent
-- DateAdded of the corresponding SequenceNumber in the Part table per Area.
UPDATE f
SET f.StartTime = MAX(p.DateAdded)
FROM
    @Filters f
    INNER JOIN Part p ON p.Area = f.Area
        AND p.SequenceNumber = f.StartingSeqNum
GROUP BY
    p.Area,
    p.SequenceNumber;

根据上面的示例数据,操作应该在下列值中填充@Filters

('A', 2, '2018-04-04')
('B', 3, '2018-04-02')
提问于
用户回答回答于

可以使用CTE来完成此操作,如下所示:

;with maxParts as
(
    select Area, SequenceNumber, MAX(dateadded) as maxDateAdded 
    from Part
    group by Area, SequenceNumber
)
UPDATE f
SET f.StartTime = p.maxDateAdded
from @Filters f
    inner join maxParts p 
        on f.Area = p.Area
        and f.StartingSeqNum = p.SequenceNumber

但是,你也可以将CTE重写为子查询:

UPDATE f
SET f.StartTime = p.maxDateAdded
from @Filters f
    inner join (
            select Area, SequenceNumber, MAX(dateadded) as maxDateAdded 
            from Part
            group by Area, SequenceNumber
        ) p 
        on f.Area = p.Area
        and f.StartingSeqNum = p.SequenceNumber
用户回答回答于

(A)

UPDATE Filters
       SET Filters.StartTime = (SELECT max(Part.DateAdded)
                                FROM Part
                                WHERE Part.Area = Filters.Area
                                      AND Part.SequenceNumber = Filters.StartingSeqNum)
       FROM @Filters Filters;

(B)

UPDATE Filters
       SET Filters.StartTime = X.StartTime
       FROM @Filters Filters
            INNER JOIN (SELECT max(Part.DateAdded) StartTime,
                               Part.Area,
                               Part.SequenceNumber
                               FROM Part
                               GROUP BY Part.Area,
                                        Part.SequenceNumber) X
                       ON X.Area = Filters.Area
                          AND X.SequenceNumber = Filters.StartingSeqNum;

扫码关注云+社区

领取腾讯云代金券