2015-10-15 113 views
0

这是我第一次在这里发帖提问,所以请温柔,我搜索的详尽尽我所能。有时候就是如何寻找答案的一半。更新从表中每条记录与多个记录多列每个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 
+0

你在这里遇到的问题是,Perf_Cat_A,B和C将全部在同一时间从pd -select中的一行进行更新 - 所以如果在那里有多行,你将不会得到作为单独的更新不同的列 –

+0

我怀疑可能是这样。希望有一个技巧,而不是使用三个单独的更新语句。再次感谢! (顺便说一句,你是怎么得到的代码片段格式对我来说很好?我试图找出如何做到这一点) –

+0

你会通过缩进4个空格来获得代码,或者编辑框上方还有一个按钮说“代码示例” –

回答

0

要更新所有的值同时,你需要有一个具有一行所有三个值数据,所以像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 

我还没有测试过这个,但希望没有错误。

0

首先使用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中,它是在连接本身。这样,您就不会影响整个数据集,而只是单独对每个子集加入。