表1:#tdac
insert #tdac(secnum,bucketcode,acc,defqty)
select 'ax1','cor',1,'012',-100
insert #tdac(secnum,bucketcode,acc,defqty)
select 'ax1','cor',2,'012',-50
表2:#dac
insert #dac(secnum,bucketcode,acc,defqty)
select 'ax1','cor',0,'012',-125
我想通过从最早的dfqty
开始从表2中减去defqty
来更新表1中的caseid
。
If #tdac.defqty-#dac.defqty > 0, then
#tdac.defqty=0 and #dac.defqty = (#tdac.defqty-#dac.defqty)
proceed to the next row.
Continue this until the value of (#tdac.defqty-#dac.defqty) becomes less than 0.
在我的示例中,我想更新表1,如下所示。请帮忙
secnum bucketcode caseid acc defqty
ax1 cor 1 012 0 ((-100 -(-125)=25)>0, So make it 0)
ax1 cor 2 012 -25 ((-50 -(-25)=-25)<0, So make it -25)
答案 0 :(得分:0)
我不确定我是否完全理解你的逻辑,但我认为这可以通过递归CTE完成:
我添加了另一个案例组来证明这种方法可以一次性处理不同的群体。
declare @tdac table(secnum varchar(100),bucketcode varchar(100),caseid int,acc varchar(100),defqty int);
insert @tdac(secnum,bucketcode,caseid,acc,defqty)
values('ax1','cor',1,'012',-100)
,('ax1','cor',2,'012',-50)
,('ax1','cor',3,'012',-150)
,('ax2','cor',1,'012',-100)
,('ax2','cor',2,'012',-100);
declare @dac table(secnum varchar(100),bucketcode varchar(100),caseid int,acc varchar(100),defqty int);
insert @dac(secnum,bucketcode,caseid,acc,defqty)
values('ax1','cor',0,'012',-125)
,('ax2','cor',0,'012',-150);
- 第一个CTE将找到所有不同的组,并将@dac的值作为起始值添加到集合
WITH DistinctGroups AS
(
SELECT t.secnum,t.bucketcode,t.acc,d.defqty
FROM @tdac AS t
LEFT JOIN @dac AS d ON d.secnum=t.secnum and d.bucketcode=t.bucketcode AND d.acc=t.acc
GROUP BY t.secnum,t.bucketcode,t.acc,d.defqty
)
- 递归CTE
,recursiveCTE AS
(
--anchor: Get the rows with the minimal caseid from each group
SELECT t.secnum,t.bucketcode,t.caseid,t.acc,t.defqty,CASE WHEN x.NewQty>0 THEN 0 ELSE x.NewQty END AS NewQty,CASE WHEN x.NewQty>0 THEN x.NewQty ELSE 0 END AS NewDiff
FROM @tdac AS t
INNER JOIN DistinctGroups AS gr ON t.secnum=gr.secnum AND t.bucketcode=gr.bucketcode AND t.acc=gr.acc
CROSS APPLY(SELECT t.defqty-gr.defqty AS NewQty) AS x
WHERE t.caseid=(SELECT MIN(caseid) FROM @tdac AS t2 WHERE t2.secnum=gr.secnum AND t2.bucketcode=gr.bucketcode AND t2.acc=gr.acc)
UNION ALL
--find the row with the next caseid and add the diff value of the previous row
SELECT t.secnum,t.bucketcode,t.caseid,t.acc,t.defqty,CASE WHEN x.NewQty>0 THEN 0 ELSE x.NewQty END AS NewQty,CASE WHEN x.NewQty>0 THEN x.NewQty ELSE 0 END AS NewDiff
FROM @tdac AS t
INNER JOIN recursiveCTE AS r ON t.secnum=r.secnum AND t.bucketcode=r.bucketcode AND t.acc=r.acc
CROSS APPLY(SELECT t.defqty+r.NewDiff AS NewQty) AS x
WHERE t.caseid=r.caseid+1
)
select *
from recursiveCTE
order by secnum,caseid
结果
ax1 cor 1 012 -100 0 25
ax1 cor 2 012 -50 -25 0
ax1 cor 3 012 -150 -150 0
ax2 cor 1 012 -100 0 50
ax2 cor 2 012 -100 -50 0
答案 1 :(得分:0)
UPDATE #tdac SET defqty = CASE WHEN ( (#tdac.defqty) -(F.defqty) ) > 0 THEN 0 ELSE ( (#tdac.defqty) -(F.defqty) ) END FROM #dac F WHERE F.secnum = #tdac.secnum
答案 2 :(得分:0)
为defqty构建一个运行总计(使用sum() over()
)。然后更新总数在校正值范围内的位置。
update tdac
set defqty = case when tdac.total >= dac.total then 0 else tdac.total - dac.total end
from
(
select secnum, bucketcode, acc, sum(defqty) as total
from #dac
group by secnum, bucketcode, acc
) dac
join
(
select secnum, bucketcode, acc, caseid, defqty,
sum(defqty) over (partition by secnum, bucketcode, acc order by caseid) as total
from #tdac
where defqty < 0
) tdac on tdac.secnum = dac.secnum
and tdac.bucketcode = dac.bucketcode
and tdac.acc = dac.acc
and tdac.total - tdac.defqty >= dac.total;
我怀疑您想加入secnum
,bucketcode
和acc
。如果不是这种情况,请更改GROUP BY
,PARTITION BY
和ON
条款。
我编写了查询,以便能够处理#dac
中针对同一secnum
,bucketcode
和acc
的多个条目。如果这三者是唯一的(当然是表的主键),那么您当然不需要聚合子查询,而是可以直接从#dac
中选择。
以下是存储的测试:http://rextester.com/VJJY97875。