【问题标题】:Update column value based on row value in the same row, row by row根据同一行中的行值逐行更新列值
【发布时间】:2020-04-13 09:57:16
【问题描述】:

我有一张带有memberIDDate 的表,如下所示:

MEM_ID          DATE        ttl_sales
-------------------------------------
19960124000007  2020-01-19  NULL
19960131001079  2020-01-20  NULL
19960203001249  2020-01-07  NULL
19960205000213  2020-01-14  NULL

我需要从sales_table 更新ttl_sales,条件是使用同一行中的MEM_ID 以及同一行中DATE 之前发生的事务。

我以后可能需要使用类似的功能,但条件更复杂(在给DATE之前加上在某些商店交易,某些产品等),因此欢迎使用相关关键字和解决方案。

我正在使用 SQL Server。

谢谢。

【问题讨论】:

  • 要求您提供预期的输出,如果您到目前为止已经尝试了预期输出的说明/逻辑,该怎么办。

标签: sql sql-server sql-update


【解决方案1】:

最简单的方法是协调一个子查询,根据成员 mem_id 对 sales 中的行求和:

UPDATE members
SET ttl_sales = (
  SELECT sum(s.amount) 
  FROM sales s 
  WHERE s.sale_date < members.[date] and s.mem_id = members.mem_id
)

我假设 ttl_sales 是总销售额。如果是计数,请使用COUNT(*) 而不是SUM(amount)

您可以在 WHERE 中添加更多子句来满足您对产品、商店等的要求

【讨论】:

    【解决方案2】:

    在 SQL Server 中,您可以使用可更新的 CTE 和窗口函数。例如,如果你想要累计数,你可以使用row_number()

    with toupdate as (
          select t.*,
                 row_number() over (partition by memberId order by date) as seqnum
          from t
         )
    update toupdate
         set ttl_sales = seqnum;
    

    窗口函数非常灵活,所以它们可能可以做你想做的事情。

    【讨论】:

      【解决方案3】:

      您还可以使用包含INNER JOINSUM 聚合子查询的公用表表达式:

      WITH s AS
      (
       SELECT s.Mem_ID AS Mem_ID_s, 
              SUM( COALESCE(s.ttl_sales,0) ) AS ttl_sales_s
         FROM sales s
         JOIN members m 
           ON m.Mem_ID = s.Mem_ID
        WHERE s.Date < m.Date
        GROUP BY s.Mem_ID
      )
      UPDATE m
         SET m.ttl_sales = s.ttl_sales_s
        FROM members as m
        INNER JOIN s 
           ON m.Mem_ID = s.Mem_ID_s;
      

      另请注意,对于NULL 列的NULL 值的情况,使用COALESCE() 函数很重要。

      Demo

      【讨论】:

      • 考虑在 SUM 中保留 NULL 可能需要了解 -1 + 1(no records) 之间的区别
      • 好吧,好吧,这也可能是另一个选择@CaiusJard
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      相关资源
      最近更新 更多