我需要更新一些记录,这里是表结构
表A是我们更新某些记录所需的主要内容 甲(ID,DataYear0,DataYear1,DataYear3)
表B除了我们需要的数据之外还有其他一些数据 B(标识,年份,DataYear)
表B的示例数据: B(ABC,1950,1.25) B(ABC,1951,1.29) .. .. B(ABC,2008,1.67) B(ABC,2009,1.23) B(ABC,2010,1.52) B(ABC,2011,1.78) B(ABC,2012,NULL)
2012年作为本年度,我需要更新表A中前三年的数据值(即2011,2010,2009)
因此,对于上面的例子,表A需要更新为A(abc,1.78,1.52,1.23)。同样,其他记录也需要更新。
Id是两个表的主键。
到目前为止我的查询是
UPDATE A SET
DataYear0 = CASE WHEN Year+1 = YEAR(GETDATE()) THEN DataYear END,
DataYear1 = CASE WHEN Year+2 = YEAR(GETDATE()) THEN DataYear END,
DataYear2 = CASE WHEN Year+3 = YEAR(GETDATE()) THEN DataYear END
FROM A
LEFT JOIN B
ON A.Id=B.Id
这不起作用,因为我认为除了我们想要的年份,即仅仅过去三年,它还会返回额外的年份记录
UPDATE A SET
DataYear0 = CASE WHEN Year+1 = YEAR(GETDATE()) THEN DataYear END,
DataYear1 = CASE WHEN Year+2 = YEAR(GETDATE()) THEN DataYear END,
DataYear2 = CASE WHEN Year+3 = YEAR(GETDATE()) THEN DataYear END
FROM A
LEFT JOIN B
ON A.Id=B.Id
GROUP BY Id,Year,DataYear
HAVING ((YEAR(GETDATE())-3) <= Year) AND (Year <> YEAR(GETDATE()))
但数据仍未更新。
尝试使用CTE
;WITH cte AS
(
SELECT
A.Id
,B.Year
,B.DataYear
,ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Year DESC) as row
FROM A
LEFT JOIN B
ON A.Id=B.Id
GROUP BY Id,Year,DataYear
HAVING ((YEAR(GETDATE())-3) <= Year) AND (Year <> YEAR(GETDATE()))
)
UPDATE
A.DataYear0 = CASE WHEN row=1 THEN DataYear END
,A.DataYear1 = CASE WHEN row=2 THEN DataYear END
,A.DataYear2 = CASE WHEN row=3 THEN DataYear END
FROM A
LEFT JOIN cte
ON A.Id = cte.Id
数据仍未更新。我很感激任何人可能有的建议。非常感谢提前。
答案 0 :(得分:2)
问题源于尝试从多行更新单行。要查看它,请将更新转换为选择。在这种情况下,最后一个更新程序获胜,将其他两列保留为空。要解决此问题,请使用子查询或某种方式将行转换为列,例如pivot。
现在,过度工程的乐趣:
update A
set DataYear0 = pvt.[0],
DataYear1 = pvt.[1],
DataYear2 = pvt.[2]
from A
inner join
(
select u.ID, u.[0], u.[1], u.[2]
from
(
select b.id,
3 - (year(getdate()) - b.Year) YearOffset,
b.DataYear
from B
where b.Year >= year(getdate()) - 3
and b.Year < year(getdate())
) p
pivot (min(DataYear)
for YearOffset in ([0], [1], [2])
) u
) pvt
on A.id = pvt.id;
答案 1 :(得分:2)
你可以这样做:
UPDATE a
SET DataYear0 = COALESCE(d0.DataYear,DataYear0),
DataYear1 = COALESCE(d1.DataYear,DataYear1),
DataYear2 = COALESCE(d2.DataYear,DataYear2)
FROM A a
LEFT JOIN B d0 ON d0.Id = a.Id and d0.[Year] = YEAR(GETDATE())-1
LEFT JOIN B d1 ON d1.Id = a.Id and d1.[Year] = YEAR(GETDATE())-2
LEFT JOIN B d2 ON d2.Id = a.Id and d2.[Year] = YEAR(GETDATE())-3
答案 2 :(得分:0)
UPDATE A
SET
DataYear0 = (SELECT DataYear FROM B WHERE A.id = B.id AND Year = YEAR(GETDATE()) - 1),
DataYear1 = (SELECT DataYear FROM B WHERE A.id = B.id AND Year = YEAR(GETDATE()) - 2),
DataYear2 = (SELECT DataYear FROM B WHERE A.id = B.id AND Year = YEAR(GETDATE()) - 3)
FROM
中的UPDATE
子句不是标准SQL。这种方法似乎有点冗长,但这是正确的方法,优化器仍然可以有效地处理它。
如果任何子查询不是标量结果,那么它也会导致错误,这是一件好事。其他答案将允许这样做。