我想得到你们的一些确认:
我有一个视图,其中包括(其中包括)列time_in,time_out,Company,weight,它显示公司何时将重量放入仓库以及何时(如果有的话)将其取出。所以它看起来像这样:
time_in time_out company weight
1-07-2013 3-07-2013 A 10
2-07-2013 NULL A 15
2-07-2013 4-07-2013 B 5
3-07-2013 NULL B 1
等
现在我想为每家公司的每一天做一个平衡,所以它会是这样的:
Date Company Balance
1-07-2013 A 10
1-07-2013 B 0
2-07-2013 A 25
2-07-2013 B 5
3-07-2013 A 15
3-07-2013 B 6
4-07-2013 A 15
4-07-2013 B 1
等
虽然我知道如何运行一个基本的运行总计,即
SELECT a.time_IN, a.weight, (SELECT sum (b.weight) from DEPOT b
where b.time_in <= a.time_in) as total_weight from DEPOT a
我可以猜到平衡就像是
SELECT a.time_IN, a.weight, ((SELECT sum (b.weight)
from DEPOT b where b.time_in <= a.time_in)
-(SELECT sum (c.weight) from DEPOT c
where a.time_out >= c.time_out) as balance from DEPOT a
我是否朝着正确的方向前进? 另外,我是否必须简单地添加GROUP BY公司以获取公司信息?
答案 0 :(得分:3)
如果您想要每日记录,则需要一个列出所有日期的驱动程序表,然后使用您设置的时间输入/输出范围到该表的JOIN
。然后我认为在加入后将重量值设置为每日水平是有意义的,因此您可以简单地完成运行总计。这有效:
DECLARE @min_dt date = (SELECT MIN(time_in) FROM #Table1)
,@max_dt date = (SELECT MAX(time_out) FROM #Table1)
;WITH cte AS (SELECT @min_dt AS dt
UNION ALL
SELECT DATEADD(DAY,1,dt)
FROM cte
WHERE dt < @max_dt)
,cte2 AS (SELECT a.dt,b.company,CASE WHEN a.dt = b.time_in THEN b.weight
WHEN a.dt = b.time_out THEN b.weight *-1
ELSE 0
END AS signed_weight
FROM cte a
LEFT JOIN #Table1 b
ON a.dt BETWEEN b.time_in AND ISNULL(b.time_out,'2099-12-31'))
SELECT dt,company,(SELECT SUM(b.signed_Weight)
FROM cte2 b
WHERE a.company = b.company
AND b.dt <= a.dt)
FROM cte2 a
GROUP BY a.dt,company
ORDER BY a.company, dt
OPTION (MAXRECURSION 0);
演示:SQL Fiddle
注意:如果您希望每家公司每天(上述版本仅涵盖每家公司的最小/最大条目之间的日期),您需要驱动程序表以包含所有公司/日期组合。