当前位置: 代码迷 >> Sql Server >> (急)SQL2000 按月统计期初、期终数据
  详细解决方案

(急)SQL2000 按月统计期初、期终数据

热度:102   发布时间:2016-04-24 09:13:37.0
(急)SQL2000 按月统计期初、期末数据
引用他人数据:
--结存表
CREATE TABLE Stocks(Item varchar(10),Period int,Balance int)
 INSERT Stocks SELECT 'aa',200501,100
 UNION  ALL    SELECT 'cc',200501,100

--明细账数据
CREATE TABLE tb(
 ID int IDENTITY PRIMARY KEY,
 Item varchar(10),  --产品编号
Quantity int,      --交易数量
Flag bit,          --交易标志,1代表入库,0代表出库,这样可以有效区分退货(负数)
Date datetime)     --交易日期
INSERT tb SELECT 'aa',100,1,'2005-1-1'
 UNION ALL SELECT 'aa',90 ,1,'2005-2-1'
 UNION ALL SELECT 'aa',55 ,0,'2005-2-1'
 UNION ALL SELECT 'aa',-10,1,'2005-2-2'
 UNION ALL SELECT 'aa',-5 ,0,'2005-2-3'
 UNION ALL SELECT 'aa',200,1,'2005-2-2'
 UNION ALL SELECT 'aa',90 ,1,'2005-2-1'
 UNION ALL SELECT 'aa',-10,1,'2005-3-2'
 UNION ALL SELECT 'bb',95 ,1,'2005-2-2'
 UNION ALL SELECT 'bb',65 ,0,'2005-2-3'
 UNION ALL SELECT 'bb',-15,1,'2005-2-5'
 UNION ALL SELECT 'bb',-20,0,'2005-2-5'
 UNION ALL SELECT 'bb',100,1,'2005-2-7'
 UNION ALL SELECT 'cc',100,1,'2005-1-7'
 GO
==============说明=================
Item(品名)    Date(年-月)       Opening(本月期初)    IN(本月入库)     IN_Retrun(本月入库退回)   OUT(本月出库)   OUT_Return(本月出库退回)   Balance(本月期末/本月库存) 
=========大概结果如下===================
Item    Date       Opening    IN     IN_Retrun   OUT   OUT_Return   Balance 
 ---------- ---------------- -------------- ----------- ---------------- ----------- ------------------- ----------- 
 aa     2005-02      225      200     10          0       5            420
 bb     2005-02      0        195     15          65      20           135
 cc     2005-02      100       0      0           0       0            100
 aa     2005-03      420       0      10          0       0            410

------解决思路----------------------
SELECT Item,CONVERT(VARCHAR(7),Date,120)Date
,MIN(Opening)Opening
,ISNULL(SUM(CASE WHEN Flag>0 AND Quantity>=0 THEN Quantity END),0)[IN]
,ABS(ISNULL(SUM(CASE WHEN Flag>0 AND Quantity<0 THEN Quantity END),0))[IN_Retrun]
,ISNULL(SUM(CASE WHEN Flag<=0 AND Quantity>=0 THEN Quantity END),0)[OUT]
,ABS(ISNULL(SUM(CASE WHEN Flag<=0 AND Quantity<0 THEN Quantity END),0))[OUT_Return]
,MAX(Balance)Balance
FROM (
SELECT T1.ID,T1.Item,T1.Date,T1.Flag,T1.Quantity
,ISNULL(T3.Balance,0)+SUM(CASE WHEN T1.ID=T2.ID THEN 0 WHEN T2.Flag>0 THEN T2.Quantity ELSE -T2.Quantity END)Opening
,ISNULL(T3.Balance,0)+SUM(CASE WHEN T2.Flag>0 THEN T2.Quantity ELSE -T2.Quantity END)Balance
FROM TB T1
JOIN TB T2 ON T1.Item=T2.Item AND(T1.Date>T2.Date OR(T1.Date=T2.Date AND T1.ID>=T2.ID))
LEFT JOIN Stocks T3 ON T1.Item=T3.Item
GROUP BY T1.ID,T1.Item,T1.Date,T1.Flag,T1.Quantity,T3.Balance
)T
--WHERE Date>='2005-01-01'时间条件放在此处
GROUP BY Item,CONVERT(VARCHAR(7),Date,120)
ORDER BY Item,Date--排序你可以根据你的需要进行修改

------解决思路----------------------

-- 试试这个,我剔除了 2005 以上的语法,看 2000 下能不能跑通。
declare  @t table
(
item varchar(10) , 
tdate varchar(10) ,
Opening int , 
[IN] int, 
IN_Retrun int , 
[OUT] int ,
OUT_Return int , 
Balance int 
)
insert into @t(item , tdate,[in],IN_Retrun,[out],OUT_Return)
select 
item , convert(varchar(7),[date],120) ,
sum(case when Flag = 1 and Quantity > 0 then Quantity else 0 end) ,
sum(case when Flag = 1 and Quantity < 0 then -Quantity else 0 end) ,
sum(case when Flag = 0 and Quantity > 0 then Quantity else 0 end) ,
sum(case when Flag = 0 and Quantity < 0 then -Quantity else 0 end) 
from tb 
group by item , convert(varchar(7),[date],120)

-- 计算当月净结余
update @t set Balance = [IN] - IN_Retrun - [OUT] + OUT_Return

-- select * from @t
select item, tdate , opening , [IN] , IN_Retrun , [OUT] , OUT_Return ,
opening + balance as balance
from (
select A.item , A.tdate , 
 (select isnull(SUM(b.Balance),0) from @t B where A.item = b.item and a.tdate > b.tdate) as Opening , 
 A.[IN] , A.IN_Retrun , A.[OUT] , A.OUT_Return , A.Balance
from @t A 
) x 

item       tdate      opening     IN          IN_Retrun   OUT         OUT_Return  balance
---------- ---------- ----------- ----------- ----------- ----------- ----------- -----------
aa         2005-01    0           100         0           0           0           100
cc         2005-01    0           100         0           0           0           100
aa         2005-02    100         380         10          55          5           420
bb         2005-02    0           195         15          65          20          135
aa         2005-03    420         0           10          0           0           410

(5 行受影响)


------解决思路----------------------
设计有误。
Stocks表的字段就应该按照你需要的结果这样设计。
然后按月统计下来,把结果永久保存在Stocks表中。
查询就从Stock表中直接取,不能每次查询都重新计算。
  相关解决方案