以下链接中的表格:
Result
列是T-SQL
查询的结果,其中每条记录通过帐单反映чprodump-modelч从чemployeeч到另一个的移动:amount
从employee
移出,金额将填入Amount_Out
列,反之亦然。
例如:第3行和第4行显示40件产品hp
已从emp1
移至emp3
通过代码111
的帐单。此移动会将emp1
的此产品总金额降低为60
,并将emp3
的同一产品的总金额增加为40
。
现在,我需要在查询中计算每条记录中的结果,以显示员工保管产品的总金额,直至记录中的日期为止:
结果=为所有先前账单计算的金额+ Amount_In - Amount_Out
这意味着结果将取决于先前记录的值。如何通过SQL Server 2008中的查询实现这一目标?什么是最好的实现它,存储过程或视图?
答案 0 :(得分:0)
您可以使用相关子查询执行此操作。如果AND it.No <= ot.No
不是连续的,则将AND it.Date <= ot.Date
更改为No
:
DECLARE @t TABLE
(
No INT ,
Employee CHAR(4) ,
Model CHAR(4) ,
Date DATE ,
Bill CHAR(3) ,
Income MONEY ,
Outcome MONEY
)
INSERT INTO @t
VALUES ( 1, 'emp1', 'hp', '20140101', '000', 100, 0 ),
( 2, 'emp1', 'dell', '20140101', '000', 100, 0 ),
( 3, 'emp1', 'hp', '20140308', '111', 0, 40 ),
( 4, 'emp3', 'hp', '20140308', '111', 40, 0 ),
( 5, 'emp3', 'hp', '20140408', '222', 0, 20 ),
( 6, 'emp2', 'hp', '20140408', '222', 20, 0 ),
( 7, 'emp1', 'hp', '20140608', '333', 0, 5 ),
( 8, 'emp2', 'hp', '20140608', '333', 5, 0 ),
( 9, 'emp1', 'dell', '20150101', '444', 0, 40 )
SELECT * ,
( SELECT SUM(Income - Outcome)
FROM @t it
WHERE it.Model = ot.Model
AND it.Employee = ot.Employee
AND it.No <= ot.No
) AS Result
FROM @t ot
输出:
No Employee Model Date Bill Income Outcome Result
1 emp1 hp 2014-01-01 000 100.00 0.00 100.00
2 emp1 dell 2014-01-01 000 100.00 0.00 100.00
3 emp1 hp 2014-03-08 111 0.00 40.00 60.00
4 emp3 hp 2014-03-08 111 40.00 0.00 40.00
5 emp3 hp 2014-04-08 222 0.00 20.00 20.00
6 emp2 hp 2014-04-08 222 20.00 0.00 20.00
7 emp1 hp 2014-06-08 333 0.00 5.00 55.00
8 emp2 hp 2014-06-08 333 5.00 0.00 25.00
9 emp1 dell 2015-01-01 444 0.00 40.00 60.00
答案 1 :(得分:0)
Sql 2008无法访问Sql2012中的其他分析函数,例如LEAD和LAG,因此您需要采用these here之一的解决方法
这是递归CTE实现的一个例子。
请注意,这取决于能否对Employee,ProductModel分组中的连续移动进行逐步编号(1,2,3等)而没有任何歧义,因为这用于JOIN条件(Sequence to Sequence + 1) 。例如,如果存在平局,您将获得不稳定的结果。
WITH RankedByEmpProduct AS
(
SELECT No, Employee, Product_Model, Date, Bill_Code, Amount_In,
Amount_Out, Amount_In-Amount_Out AS Nett,
DENSE_RANK() OVER (PARTITION BY Employee, Product_Model
ORDER BY No ASC) AS EmpModelSeq
FROM ProductModel
),
RecursiveRunningTotal AS
(
SELECT No, Employee, Product_Model, Date, Bill_Code, Amount_In,
Amount_Out, EmpModelSeq, Amount_In-Amount_Out AS Nett,
Amount_In-Amount_Out AS RunningTotal
FROM RankedByEmpProduct rep
WHERE EmpModelSeq = 1
UNION ALL
SELECT rep.No, rep.Employee, rep.Product_Model, rep.Date, rep.Bill_Code,
rep.Amount_In, rep.Amount_Out, rep.EmpModelSeq,
rep.Amount_In-rep.Amount_Out AS Nett,
rrt.RunningTotal + rep.Amount_In - rep.Amount_Out AS RunningTotal
FROM RankedByEmpProduct rep
INNER JOIN RecursiveRunningTotal rrt
ON rep.Employee = rrt.Employee AND rep.Product_Model = rrt.Product_Model
AND rep.EmpModelSeq = rrt.EmpModelSeq + 1
)
SELECT * FROM RecursiveRunningTotal
ORDER BY No ASC;
答案 2 :(得分:0)
您可以通过简单的子查询获取结果。
SELECT No,Employee,Product_Model,[Date],Bill_Code,Amount_In,Amount_Out,
(
SELECT SUM
(
SELECT D1.Amount_In - D0.Amount_Out AS subTotal
FROM Table_Name AS D1
WHERE
(
D1.[Date] < D0.[Date]
)
OR
(
D1.[Date] = D0.[Date]
AND
D1.No <= D0.No
)
)
) AS Result
FROM Table_Name D0
ORDER BY D0.No, D0.[Date]
实际输出应为:
No Employee Product_Model Date Bill_Code Amount_In Amount_Out Result
1 emp1 hp 2014-01-01 000 100.00 0.00 100.00
2 emp1 dell 2014-01-01 000 100.00 0.00 200.00
3 emp1 hp 2014-03-08 111 0.00 40.00 160.00
4 emp3 hp 2014-03-08 111 40.00 0.00 200.00
5 emp3 hp 2014-04-08 222 0.00 20.00 180.00
6 emp2 hp 2014-04-08 222 20.00 0.00 200.00
7 emp1 hp 2014-06-08 333 0.00 5.00 195.00
8 emp2 hp 2014-06-08 333 5.00 0.00 200.00
9 emp1 dell 2015-01-01 444 0.00 40.00 160.00