根据同一行中的行值逐行更新列值
Posted
技术标签:
【中文标题】根据同一行中的行值逐行更新列值【英文标题】:Update column value based on row value in the same row, row by row 【发布时间】:2020-04-13 09:57:16 【问题描述】:我有一张带有memberID
和Date
的表,如下所示:
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。
谢谢。
【问题讨论】:
要求您提供预期的输出,如果您到目前为止已经尝试了预期输出的说明/逻辑,该怎么办。 【参考方案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 JOIN
和SUM
聚合子查询的公用表表达式:
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以上是关于根据同一行中的行值逐行更新列值的主要内容,如果未能解决你的问题,请参考以下文章