2017-05-04 62 views
-1

我有一个需求,我需要在多个记录中均匀分配一个值。下面是我的数据看起来像价值分摊的T-SQL查询

Relationship Table 
------------------------------------------------------- 
CategoryID   SubCategoryID 
------------------------------------------------------- 
101    1 
101    2 
101    3 
102    4 
102    5  

Table 1 
------------------------------------------------------- 
BatchLine ID  CategoryID  Amount 
------------------------------------------------------- 
1     101    10 
2     102    100 
3     101    100 

Table 2 
------------------------------------------------------------------- 
LineID BatchLineID CategoryID SubCategoryID LineValue 
------------------------------------------------------------------- 
1   1    101   1    3.33 
2   1    101   2    3.33 
3   1    101   3    3.33 
4   2    102   4    66.66 
5   2    102   5    33.33 
6   3    101   1    33.33 
7   3    101   2    33.33 
8   3    101   3    33.33  

在“表2”中的“LineValue”是从“表1”上的“金额”字段进行的计算的结果,然后将最终值四舍五入到两位小数点。在某些情况下,舍入过程会导致与“表格1”中的“金额”字段存在一些差异。

Difference 
------------------------------------------------------------------ 
BatchLineID CategoryID Amount SumofLineValue 
------------------------------------------------------------------ 
1    101   10  9.99 
2    102   100  99.99 
3    101   100  99.99 

为了从“表1”匹配“金额”值,我们需要与类别ID组中添加“0.01”到每个“LineID”直到的“LineValue”等于它的总和。

还有一个条件,在'CategoryID'101的情况下'表2'中有两组数据。我们将“0.01”添加到LineID 1,这将使总和与“表1”中的“金额”字段匹配。当我们需要分摊第二组时,需要以“线路ID”7而不是6开始。下面是我预期的数据。

Expected Output 
------------------------------------------------------------------- 
LineID BatchLineID CategoryID SubCategoryID LineValue 
------------------------------------------------------------------- 
1   1    101   1    3.33 + 0.01 
2   1    101   2    3.33 
3   1    101   3    3.33 
4   2    102   4    66.66 + 0.01 
5   2    102   5    33.33 
6   3    101   1    33.33 
7   3    101   2    33.33 + 0.01 
8   3    101   3    33.33 
+0

是否将LineValue定义为十进制(x,2)? – McNets

+0

@McNets是,它被定义为十进制(X,2) – Prakazz

+0

批量最多有3行吗? – McNets

回答

0

只要没有标志哪些记录必须更新,该解决方案就会更新每个组的第一条记录。

with rn as 
(
    select t2.LineID, t1.BatchLineID, t1.CategoryID, t1.Amount, t2.SubCategoryID, 
      sum(t2.LineValue) over (partition by t2.BatchLineID, t2.CategoryID) as ActSum, 
      row_number() over (partition by t2.BatchLineID, t2.CategoryID order by SubCategoryID) as RNum 
    from  t1 
    left join t2 
    on  t1.BatchLineID = t2.BatchLineID 
    and  t1.CategoryID = t2.CategoryID 
) 
update  t2 
set  LineValue = LineValue + (Amount - ActSum) 
from  t2 tt2 
inner join rn 
on   tt2.LineID = rn.LineID 
where  RNum = 1 
and  Amount <> ActSum; 
GO 
select * from t2; 
GO 
 
LineID | BatchLineID | CategoryID | SubCategoryID | LineValue 
-----: | ----------: | ---------: | ------------: | :-------- 
    1 |   1 |  101 |    1 | 3.34  
    2 |   1 |  101 |    2 | 3.33  
    3 |   1 |  101 |    3 | 3.33  
    4 |   2 |  102 |    4 | 66.67  
    5 |   2 |  102 |    5 | 33.33  
    6 |   3 |  101 |    1 | 33.34  
    7 |   3 |  101 |    2 | 33.33  
    8 |   3 |  101 |    3 | 33.33  

dbfiddle here

+0

要求是不添加相同的' SubCategoryID'。对于'CategoryID'第二组的情况101 LineID 7应该添加'0.01'。这是真正的抓住这里。 – Prakazz

+0

好吧,让我想想解决方案 – McNets

0

适应的fiddl从McNets E,你可以使用dense_rank()以确定哪一行应该被更新:

with cte1 as (
    select t2.LineID, t1.BatchLineID, t1.CategoryID, t1.Amount, t2.SubCategoryID, 
      sum(t2.LineValue) over (partition by t2.BatchLineID, t2.CategoryID) as ActSum, 
      row_number() over (partition by t2.BatchLineID, t2.CategoryID order by SubCategoryID) as RNum, 
      dense_rank() over (partition by t1.CategoryID order by t1.BatchLineID) as drank 
    from  t1 
    left join t2 
    on  t1.BatchLineID = t2.BatchLineID 
    and  t1.CategoryID = t2.CategoryID 
) 
select a.LineID, a.BatchLineID, a.CategoryID, a.SubCategoryID, case when drank = rnum then a.LineValue + (b.Amount - b.ActSum) else a.LineValue end as LineValue 
from t2 a 
left join cte1 b 
    on a.LineID = b.LineID 

需要注意的是,你可以运行到随后的群体没有足够的行,因此没有行被更新的问题。

+0

谢谢你的努力乔希。但不一定我们需要在第二个实例和第三个实例中添加第二行和第三行。如果我们停止在第一组中的第二个“SubCategoryID”分配,那么它需要是动态的,然后我们需要在第二组中的第三个“SubCategoryID”开始分摊。此外,我们需要在记录中均匀添加'0.01',而不是将差异添加到一条记录。 – Prakazz

+0

也许你的问题需要这些细节呢? –