我有4个结果集,我将其移动到一个临时表中以用于报告目的:
Date Issued_Id Item_Name Qty_Issued Qty_Return Qty_Damage Type Balance OPBal
----------------------------------------------------------------------------------------------
Dec 18 2014 6003 Bed Covers 4 0 0 IS NULL 245
Dec 18 2014 6008 Bed Covers 4 0 0 IS NULL 245
2014-12-17 6000 Bed Covers 0 22 0 RT NULL 245
2014-12-22 7002 Bed Covers 0 10 0 RT NULL 245
现在我必须在(OPBal=Qty_Issued + OPBal)
时添加Type="IS"
,在(OPBal=Qty_Return - OPBal)
时减去type="RT"
。
它应该像这样打印
Date Issued_Id Item_Name Qty_Issued Qty_Return Qty_Damage Type Balance OPBal
---------------------------------------------------------------------------------------------
Dec 18 2014 6003 Bed Covers 4 0 0 IS NULL 249
Dec 18 2014 6008 Bed Covers 4 0 0 IS NULL 253
2014-12-17 6000 Bed Covers 0 22 0 RT NULL 231
2014-12-22 7002 Bed Covers 0 10 0 RT NULL 221
如何在SQL Server中使用游标?
答案 0 :(得分:1)
目前还不清楚问题中四行的排序标准是什么 - 既不是按日期也不是Issued_Id
。我将假设条目应该由Issued_Id
订购,并且您的示例是错误的。
获得累积总和的最简单方法是使用window query。
SELECT Date, Issued_Id, Item_Name, Qty_Issued, Qty_Return, Qty_Damage, Type, Balance
, SUM(
CASE WHEN Type='IS' THEN Qty_Issued
WHEN Type='RT' THEN -Qty_Return
END
) OVER (
ORDER BY Issued_Id ROWS UNBOUNDED PRECEDING
) + OPBal AS OPBal
FROM #Temp1
ORDER BY Issued_Id;
甚至可以通过完全忽略Type
列和CASE
表达式来简化它。
SELECT Date, Issued_Id, Item_Name, Qty_Issued, Qty_Return, Qty_Damage, Type, Balance
, SUM(Qty_Issued - Qty_Return)
OVER (ORDER BY Issued_Id ROWS UNBOUNDED PRECEDING) + OPBal AS OPBal
FROM #Temp1
ORDER BY Issued_Id;
上述查询的设置:
CREATE TABLE #Temp1
( Date DATE NOT NULL
, Issued_Id INTEGER NOT NULL
, Item_Name VARCHAR(32) NOT NULL
, Qty_Issued DECIMAL NOT NULL DEFAULT 0
, Qty_Return DECIMAL NOT NULL DEFAULT 0
, Qty_Damage DECIMAL NOT NULL DEFAult 0
, Type VARCHAR(2) NOT NULL
, Balance DECIMAL
, OPBal DECIMAL NOT NULL
);
INSERT INTO #Temp1 VALUES
('2014-12-18', 6003, 'Bed Covers', 4, 0, 0, 'IS', NULL, 245),
('2014-12-18', 6008, 'Bed Covers', 4, 0, 0, 'IS', NULL, 245),
('2014-12-17', 6000, 'Bed Covers', 0, 22, 0, 'RT', NULL, 245),
('2014-12-22', 7002, 'Bed Covers', 0, 10, 0, 'RT', NULL, 245);
答案 1 :(得分:0)
试试这个
SELECT [Date],
Issued_ID,
Item_Name,
Qty_Issued,
Qty_Return,
Qty_Damage,
[Type],
Balance,
OPBal= CASE
WHEN TYPE = 'IS' THEN Qty_Issued + OPBal
WHEN TYPE = 'RT' THEN Qty_Return - OPBal
ELSE 0
END
FROM #TEMP
答案 2 :(得分:0)
目前尚不清楚您的记录是由哪些人订购的。它似乎是Date(最早的第一个)和Issue_Id(最小的第一个)。如果我错了,只需根据您的意愿通过以下声明中的条款更改顺序。
你正在寻找的是一种运行总计,有条件的Qty_Issued和Qty_Return得到总结。通过使用带有窗口子句的SUM的分析使用,您可以实现这一点。
SELECT [Date], Issued_Id, Item_Name, Qty_Issued, Qty_Return, Qty_Damage, Type, Balance,
OPBal
+ SUM(case when type = 'IS' then Qty_Issued else 0 end) OVER (ORDER BY [Date] desc, issue_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- SUM(case when type = 'RT' then Qty_Return else 0 end) OVER (ORDER BY [Date] desc, issue_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS OPBal
FROM mytable
ORDER BY [Date] desc, issue_id;
由于Qty_Issued和Qty_Return数据中的零值不合适,您可能还可以使用:
SELECT [Date], Issued_Id, Item_Name, Qty_Issued, Qty_Return, Qty_Damage, Type, Balance,
OPBal
+ SUM(Qty_Issued - Qty_Return) OVER (ORDER BY [Date] desc, issue_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS OPBal
FROM mytable
ORDER BY [Date] desc, issue_id;
答案 3 :(得分:0)
CREATE TABLE #TT
(
[Date] DateTime,
Issued_Id VARCHAR(100),
Item_Name VARCHAR(100),
Qty_Issued INT,
Qty_Return INT,
Qty_Damage INT,
[Type] VARCHAR(100),
Balance INT,
OPBal INT
)
INSERT INTO #TT
SELECT 'Dec 18 2014', 6003,' Bed Covers ', 4,0,0,'IS', NULL,245 UNION ALL
SELECT 'Dec 18 2014', 6008,' Bed Covers ', 4,0,0,'IS', NULL,245 UNION ALL
SELECT '2014-12-17', 6000,' Bed Covers ', 4,22,0,'RT', NULL, 245 UNION ALL
SELECT '2014-12-22', 7002,' Bed Covers ', 4,10,0,'RT', NULL,245
--- IF you want to apply this logic with out any sort(as shown in your question)
SELECT [Date],Issued_Id, Item_Name, Qty_Issued, Qty_Return, Qty_Damage, Type, Balance,
OPBal
+ SUM(case when type = 'IS' then Qty_Issued else 0 end) OVER (ORDER BY (SELECT 1) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- SUM(case when type = 'RT' then Qty_Return else 0 end) OVER (ORDER BY (SELECT 1) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS OPBal
FROM #TT
--- IF you want to order records by [Date] & issued_id then apply this logic
SELECT [Date],Issued_Id, Item_Name, Qty_Issued, Qty_Return, Qty_Damage, Type, Balance,
OPBal
+ SUM(case when type = 'IS' then Qty_Issued else 0 end) OVER (ORDER BY [Date] ASC, issued_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
- SUM(case when type = 'RT' then Qty_Return else 0 end) OVER (ORDER BY [Date] ASC, issued_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
AS OPBal
,SUM(case when type = 'IS' then Qty_Issued else 0 end) OVER (ORDER BY [Date] ASC, issued_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
,SUM(case when type = 'RT' then Qty_Return else 0 end) OVER (ORDER BY [Date] ASC, issued_id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM #TT
答案 4 :(得分:0)
感谢大家.. 我用光标和案例得到了解决方案......
DECLARE db_cursor CURSOR for select id from #Temp1;
open db_cursor
fetch next from db_cursor into @varData
while @@FETCH_STATUS=0
begin
set @LastAmt = ( select OPBal= case
when Type='IS' then @LastAmt+Qty_Issued
when type='RT' then @LastAmt-(Qty_Return+Qty_Damage)
when type='OP' then OPBal
else 0
end
from #Temp1 where id = @varData)
update #Temp1 set OPBal= @LastAmt where id = @varData
FETCH NEXT
FROM db_cursor INTO @varData
END
CLOSE db_cursor
DEALLOCATE db_cursor
select * from #Temp1