更新从表中每条记录与多个记录多列每个ID
问题描述:
这是我第一次在这里发帖提问,所以请温柔,我搜索的详尽尽我所能。有时候就是如何寻找答案的一半。更新从表中每条记录与多个记录多列每个ID
我想要做的是用表2中的数据更新每个时期每个人的数据。有些人将有A类,B和/或C记录在表2中,但不是所有的,不一定所有的三个。
我遇到的问题是,我用来执行更新的语句将更新某些列,但不是全部。我猜这是因为更新没有承诺还一边做更新,因此它不能获取那些未提交值。
我需要做3个单独的更新语句,或者可以通过case语句处理这个问题。我在这里寻找最有效的方法。更新表1,每个期间有200万条记录。
表1 - Period_Perf
CustID
Period_Date
Perf_Cat_A
Perf_Cat_B
Perf_Cat_C
表2 - Period_Perf_Detail
CustID
Period_Date
Perf_Category (will contain A, B, or C)
Perf_Points (will contain a integer value)
这里的基本上是我一直在试图使用的语句:
UPDATE
Period_Perf
SET
Perf_Cat_A = CASE WHEN pd.Perf_Category = 'A' then pd.Total_Perf_Points else Perf_Cat_A END
Perf_Cat_B = CASE WHEN pd.Perf_Category = 'B' then pd.Total_Perf_Points else Perf_Cat_B END
Perf_Cat_C = CASE WHEN pd.Perf_Category = 'C' then pd.Total_Perf_Points else Perf_Cat_C END
from
Period_Perf
ON
INNER JOIN
(
select
CustID
,Period_Date
,Perf_Category
,sum(Perf_Points) as Total_Perf_Points
from
Period_Perf_Detail
group by CustID, Period_Date, Perf_Category
) as pd
ON
Period_Perf.CustID = pd.CustID and Period_Perf.Period_Date = pd.Period_Date
答
要更新所有的值同时,你需要有一个具有一行所有三个值数据,所以像THI s:
UPDATE P
SET
Perf_Cat_A = pd.Cat_A,
Perf_Cat_B = pd.Cat_B,
Perf_Cat_C = pd.Cat_C
from
Period_Perf P
cross apply (
select
sum(case when Perf_Category = 'A' then Perf_Points else 0 end) as Cat_A,
sum(case when Perf_Category = 'B' then Perf_Points else 0 end) as Cat_B,
sum(case when Perf_Category = 'C' then Perf_Points else 0 end) as Cat_C
from
Period_Perf_Detail D
where
D.CustID = P.CustID and
D.Period_Date = P.Period_Date
) as pd
我还没有测试过这个,但希望没有错误。
答
首先使用SELECT语句来理解您的数据,然后根据该select语句构建更新。
首先使用下面的查询来更好地理解为什么你的更新语句没有产生你想要的结果。
SELECT CASE WHEN pd.Perf_Category = 'A' THEN pd.Total_Perf_Points ELSE Perf_Cat_A END AS Perf_Cat_A
, CASE WHEN pd.Perf_Category = 'B' THEN pd.Total_Perf_Points ELSE Perf_Cat_B END AS Perf_Cat_B
, CASE WHEN pd.Perf_Category = 'C' THEN pd.Total_Perf_Points ELSE Perf_Cat_C END AS Perf_Cat_C
FROM Period_Perf
ON
INNER JOIN
(
SELECT CustID
, Period_Date
, Perf_Category
, SUM(Perf_Points) AS Total_Perf_Points
FROM Period_Perf_Detail
GROUP BY CustID
, Period_Date
, Perf_Category) AS pd
ON Period_Perf.CustID = pd.CustID
AND Period_Perf.Period_Date = pd.Period_Date
我建议您的更新以下查询。
UPDATE Period_Perf
SET Perf_Cat_A = SUM(a.Perf_Points)
, Perf_Cat_B = SUM(b.Perf_Points)
, Perf_Cat_C = SUM(c.Perf_Points)
FROM Period_Perf
LEFT JOIN Period_Perf_Detail AS a
ON Period_Perf.CustID = a.CustID
AND Period_Perf.Period_Date = a.Period_Date
AND a.Perf_Category = 'A'
LEFT JOIN Period_Perf_Detail AS b
ON Period_Perf.CustID = b.CustID
AND Period_Perf.Period_Date = b.Period_Date
AND a.Perf_Category = 'B'
LEFT JOIN Period_Perf_Detail AS c
ON Period_Perf.CustID = c.CustID
AND Period_Perf.Period_Date = c.Period_Date
AND a.Perf_Category = 'C'
GROUP BY Period_Perf.CustID , Period_Perf.Period_Date
请注意,将标准放在WHERE中,它是在连接本身。这样,您就不会影响整个数据集,而只是单独对每个子集加入。
你在这里遇到的问题是,Perf_Cat_A,B和C将全部在同一时间从pd -select中的一行进行更新 - 所以如果在那里有多行,你将不会得到作为单独的更新不同的列 –
我怀疑可能是这样。希望有一个技巧,而不是使用三个单独的更新语句。再次感谢! (顺便说一句,你是怎么得到的代码片段格式对我来说很好?我试图找出如何做到这一点) –
你会通过缩进4个空格来获得代码,或者编辑框上方还有一个按钮说“代码示例” –