根据组更新表

时间:2018-10-11 13:28:18

标签: sql sql-server

我有一张看起来像这样的桌子

ID    PCode   baseline    Period   Actual   Forecast
---------------------------------------------
1      P231        7           5       100       0
2      P231        7           6       120       0
3      P231        7           7       125       0
4      P231        7           8       130       120
5      P232        7           9       135       0
6      P232        7           5       100       0
7      P232        7           6       120       0
8      P232        7           7       125       0
9      P232        7           8       130       60
10     P233        7           9       135       0
11     P233        7           5       100       0
12     P233        7           7       120       0
13     P233        7           8       125       70
14     P231        8           1       130       0
15     P231        8           2       135       0
16     P231        8           8       130       0
17     P231        8           3       135       60
18     P232        8           2       130       0
19     P232        8           3       135       0
20     P232        8           8       130       0
21     P232        8           4       135       0
22     P232        8           5       130       70
23     P233        8           3       135       50

我在上表中要求将每个PCode的预测值移动到组中,其中基线和期间相同,然后将该基线组中该PCode的最大预测值复制到该位置

所以上表看起来像这样

ID    PCode   baseline    Period   Actual   Forecast
---------------------------------------------
1      P231        7           5       100       0
2      P231        7           6       120       0
3      P231        7           7       125       120
4      P231        7           8       130       0
5      P232        7           9       135       0
6      P232        7           5       100       0
7      P232        7           6       120       0
8      P232        7           7       125       60
9      P232        7           8       130       0
10     P233        7           9       135       0
11     P233        7           5       100       0
12     P233        7           7       120       70
13     P233        7           8       125       0
14     P231        8           1       130       0
15     P231        8           2       135       0
16     P231        8           8       130       60
17     P231        8           3       135       0
18     P232        8           2       130       0
19     P232        8           3       135       0
20     P232        8           8       130       70
21     P232        8           4       135       0
22     P232        8           5       130       0
23     P233        8           3       135       0

我考虑过尝试使用游标遍历所有基线。但是行数非常大。所以我认为CURSOR不是一个好选择

3 个答案:

答案 0 :(得分:1)

尝试一下:

update t
    set Forecast=   case
                        when t.baseline=t.Period then forecast_per_PCode.max_forecast
                        else 0
                    end
from yourtable t
inner join
(
    select t2.PCode,max(t2.Forecast) as max_forecast
    from yourtable t2
    group by t2.PCode
)forecast_per_PCode on t.PCode=forecast_per_PCode.PCode

答案 1 :(得分:0)

尝试

with perimeter as (
select Pcode from #YOURTABLE where BaseLine=Period
),
MaxForcast as (
select f1.Pcode, isnull(Max(f1.Forecast), 0) MaxForecast from #YOURTABLE f1
where exists (select * from perimeter f2 where f1.Pcode=f2.Pcode)
group by f1.Pcode
)
update f1
set f1.Forecast= case when f1.BaseLine=f1.Period then f2.MaxForecast else 0 end
from #YOURTABLE f1 inner join MaxForcast f2 on f1.Pcode=f2.Pcode

答案 2 :(得分:0)

使用可更新的CTE:

with toupdate as (
      select t.*,
             max(forecast) over (partition by pcode) as group_forecast
      from t
     )
update toupdate
    set forecast = (case when baseline = period then group_forecast else 0 end)
    where forecast <> 0 or baseline = period;

但是,为什么不将预测放到组的所有行上呢?

请注意,在这种情况下,窗口功能通常比join更快。另外,这只会更新需要更新的行。