通过子表的最大值更新父表的列值

时间:2019-06-10 10:32:53

标签: sql-server sql-update

这是我的桌子。

表1

    Id     Name    DateTime   Flag
    ==========================
    1      Name1      -        0
    2      Name2      -        1
    3      Name3      -        1

表2

    Id     Tb1Id   DateTime
    =======================
    1       1      20-09-2017
    2       1      01-09-2018
    3       2      01-09-2016
    4       2      02-09-2015 
    5       3      06-09-2016 
    6       3      10-09-2019

我想通过Table1.Id = Table2.Tb1Id联接这两个表,并从Table2获取最大日期时间值,将该值更新到table1的DateTime列,其中Table1的Flag等于1。

    Id     Name     DateTime
    ========================
    2      Name2    01-09-2016
    3      Name3    10-09-2019

到目前为止,这是我尝试过的方法。

UPDATE Table1
SET DateTime = 
(
SELECT MAX(T2.UpdatedAt) as UpdatedAt FROM Table1 AS T1
LEFT JOIN Table2 AS T2
ON T1.Id = T2.Tb1Id
WHERE T1.Flag = 1
GROUP BY T2.UpdatedAt
)

2 个答案:

答案 0 :(得分:2)

我将在此处使用更新联接:

UPDATE t1
SET DateTime = t2.MaxDateTime
FROM Table1 t1
INNER JOIN
(
    SELECT Tb1Id, MAX(DateTime) AS MaxDateTime
    FROM Table2
    GROUP BY Tb1Id
) t2
    ON t1.Id = t2.Tb1Id
WHERE
    t1.Flag = 1;

当前查询的问题是它从未将Table1的外部更新中的记录与SET子句中发生的任何事件相关联。但是,我将在这里使用更新联接,因为它更易于阅读。

请注意,如果您认为必须经常运行此更新,则可能需要考虑使用查询/视图,该报告将报告第二个表中的最大日期以及第一个表中的数据。

答案 1 :(得分:1)

这是一个简单的加入

CREATE TABLE T1(
  ID INT,
  Name VARCHAR(45),
  Date_Time DATETIME,
  Flag INT
);

INSERT INTO T1 (ID, Name, Flag) VALUES
(1, 'Name1', 0),
(2, 'Name2', 1),
(3, 'Name3', 1);

CREATE TABLE T2(
  ID INT,
  Tb1Id INT,
  Date_Time DATETIME
);

INSERT INTO T2 VALUES
(1, 1, '2017-09-20'),
(2, 1, '2018-01-09'),
(3, 2, '2016-09-01'),
(4, 2, '2015-09-02'), 
(5, 3, '2016-09-06'), 
(6, 3, '2019-09-10');

;WITH CTE AS
(
  SELECT T1.ID,
         T1.Name, --You can remove this cause I thought you want a SELECT
         MAX( T2.Date_Time ) Date_Time
  FROM T1 INNER JOIN T2
  ON T1.Id = T2.Tb1Id
  WHERE T1.Flag = 1
  GROUP BY T1.ID,
           T1.Name --And this one too
)
UPDATE T1
SET Date_Time = CTE.Date_Time
FROM T1 INNER JOIN CTE
ON T1.Id = CTE.Id;

SELECT *
FROM T1;

返回:

+----+-------+---------------------+------+
| ID | Name  |      Date_Time      | Flag |
+----+-------+---------------------+------+
|  1 | Name1 |                     |    0 |
|  2 | Name2 | 01/09/2016 00:00:00 |    1 |
|  3 | Name3 | 10/09/2019 00:00:00 |    1 |
+----+-------+---------------------+------+

Live Demo