【问题标题】:Update table with constrained values from another table使用另一个表中的约束值更新表
【发布时间】:2013-06-07 13:25:19
【问题描述】:

我对 SQL 还很陌生,现在尝试解决这个问题大约两天,但无济于事。

问题是,如何根据 Table_2 中的值更新表 Table_1 中的值,只考虑 Table_2 中特定行的子集,并且尽可能不使用游标。

更具体地说,我有这两个表:

CREATE TABLE [dbo].[Table_1](
    [ID] [int] NOT NULL,
    [LastAmount] [int] NOT NULL,
    [LastDate] [datetime] NOT NULL
) ON [PRIMARY];

CREATE TABLE [dbo].[Table_2](
    [ID] [int] NOT NULL,
    [Amount] [int] NOT NULL,
    [Date_] [datetime] NOT NULL
) ON [PRIMARY];

在表格中有以下值:

INSERT INTO [dbo].[Table_1]
    VALUES (1, 0, CONVERT(DATETIME, '19000101', 112)),
           (2, 0, CONVERT(DATETIME, '19000101', 112));

INSERT INTO [dbo].[Table_2]
    VALUES (1, 10, CONVERT(DATETIME, '19750101', 112)),
           (1, 20, CONVERT(DATETIME, '19500101', 112)),
           (1, 15, CONVERT(DATETIME, '20000101', 112)),
           (2, 30, CONVERT(DATETIME, '20100101', 112));

重点是更新 ID 与 Table_2 匹配的 Table_1 中的值。 Table_1.LastAmount 应该得到 Table_2.Amount 与最近的 Table_2.Date_。同样,对于 Table_1.LastDate,它应该得到 Table_2.Date_,其中日期是该特定 ID 的最新日期。

所以,更新前的 Table_1:

ID  |LastAmount |LastDate
----|-----------|--------
1   |0          |1900-01-01 00:00:00.0000
2   |0          |1900-01-01 00:00:00.0000

表_2:

ID  |Amount     |Date
----|-----------|--------
1   |10         |1975-01-01 00:00:00.0000
1   |20         |1950-01-01 00:00:00.0000
1   |15         |2000-01-01 00:00:00.0000
2   |30         |2010-01-01 00:00:00.0000

更新后的表_1:

ID  |LastAmount |LastDate
----|-----------|--------
1   |15         |2000-01-01 00:00:00.0000
2   |30         |2010-01-01 00:00:00.0000

我尝试使用 INNER JOIN 进行各种 UPDATE,或者在分配值时使用内联 SELECT,但它们都不起作用。非常感谢。

【问题讨论】:

  • 您是在询问 TRIGGER 解决方案吗?
  • 感谢您提供可运行的示例数据和预期结果。这有点新奇:-)
  • @Damien_The_Unbeliever 同意,如果没有脚本我可能不会打扰,所以这很好:)

标签: sql-server tsql


【解决方案1】:

update from 在这种情况下很有用。 row_number() 在这里与源表一起使用,以确定Table_2 中的最新条目。

update
    Table_1
set
    LastAmount = T2.Amount
    ,LastDate = T2.Date_
from
    (
        select
            ID
            ,Amount
            ,Date_
            ,row_number() over (partition by ID order by Date_ desc) as RowNumber
        from
            Table_2
    ) T2
where
    Table_1.ID = T2.ID
    and T2.RowNumber = 1

【讨论】:

  • 所有答案都给出了正确的结果,但是这个(使用分区)对我来说似乎是最清楚的。谢谢大家。
【解决方案2】:

这样做:

Update Table_1
Set LastAmount = Table_2.Amount,
LastDate = Table_2.[Date_]
from (SELECT ID, MAX([Date_]) as MaxDate FROM TABLE_2 GROUP BY ID) AS Max_Table2
inner join Table_2 on Max_Table2.MaxDate = Table_2.[Date_] and Max_Table2.id = Table_2.id
inner join table_1 on table_1.id = Table_2.id

基本上,您已经过滤了 table2 以获取最大日期并将所有内容连接起来以查找最后日期和金额。

【讨论】:

    【解决方案3】:

    这是对 ROW_NUMBER() 和 CTE 的简单使用:

    ;With Ordered as (
        select ID,Amount,Date_,
           ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date_ DESC) rn
        from Table_2
    )
    update t1
    set LastAmount = o.Amount,
    LastDate = o.Date_
    from
      Table_1 t1
        inner join
      Ordered o
        on
          t1.ID = o.ID and
          o.rn = 1
    

    (您可以将其编写为子查询而不是 CTE,但我在此示例中选择了 CTE)

    【讨论】:

      猜你喜欢
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-03-18
      • 2021-08-24
      • 1970-01-01
      相关资源
      最近更新 更多