每天的库存余额

时间:2013-09-20 02:52:35

标签: sql sql-server sql-server-2008

我想得到你们的一些确认:

我有一个视图,其中包括(其中包括)列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公司以获取公司信息?

1 个答案:

答案 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

注意:如果您希望每家公司每天(上述版本仅涵盖每家公司的最小/最大条目之间的日期),您需要驱动程序表以包含所有公司/日期组合。