SQL Server 2008:选择总和与行

时间:2017-03-27 09:51:03

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

我问了一个similar question recently,但实际的实现证明更难,因为它必须依赖于日期字段,而不是ID字段,所以我将开始一个新的问题,因为该方法无疑会证明有所不同。

查看下表,应返回其SUM(PurchQty)到达大于/等于“CurrentStock”的值所需的行,并且这些行必须是最新的行,根据日期。需要对此进行评估,并按“ProductCode”返回行。

因此,鉴于此表:

ID    ProductCode    Date        PurchQty    CurrentStock
1001  AB101          14/12/2016      9            14
1111  AB101          01/01/2017     18            14
1223  AB101          15/01/2017     20            14
1233  BB400          02/01/2017     50            40 
1321  AB101          31/01/2017      8            14
1400  BB400          12/12/2016     90            40
1456  CC200          13/03/2017    100            20

我们的查询应该产生结果:

ProductCode    Date         PurchQty    CurrentStock
AB101          31/01/2017      8             14 
AB101          15/01/2017     20             14
BB400          02/01/2017     50             40
CC200          13/03/2017    100             20

(注意这些是英国日期 - 年/月/年 - 但这并不重要)

4 个答案:

答案 0 :(得分:1)

试试这个,这会得到想要的结果, 我使用了递归CTE

CREATE TABLE #tst (id int,ProductCode varchar(50),[Date] Datetime,PurchQty int,CurrentStock int)
INSERT INTO #tst
SELECT 1001,'AB101','2016/12/14',9,14 UNION
SELECT 1111,'AB101','2017/01/01',18,14 UNION
SELECT 1223,'AB101','2017/01/15',20,14 UNION
SELECT 1233,'BB400','2017/01/02',50,40 UNION
SELECT 1321,'AB101','2017/01/31',8,14 UNION
SELECT 1400,'BB400','2016/12/12',90,40 UNION
SELECT 1456,'CC200','2017/03/13',100,20 

;with CTE AS (
SELECT ROW_NUMBER() over(partition by ProductCode order by [date] desc) as RowId,* from #tst
),CTE2 AS
(
SELECT RowId,id ,ProductCode ,[Date] ,PurchQty ,CurrentStock,PurchQty as Cum_Quantity from CTE as a WHERE RowId=1
UNION ALL
SELECT a.RowId,a.id ,a.ProductCode ,a.[Date] ,a.PurchQty ,a.CurrentStock, a.PurchQty+b.Cum_Quantity
FROM CTE a 
JOIN CTE2 as b  ON a.ProductCode=b.ProductCode 
WHERE a.RowId=b.RowId+1  AND a.[Date]<b.[Date] AND b.Cum_Quantity<b.CurrentStock
)
SELECT * from CTE2 order by ProductCode

答案 1 :(得分:0)

您需要一笔累计金额。在SQL Server 2008中,可以使用apply或相关子查询来完成此操作:

select t.*, t2.cume_PurchQty
from t cross apply
     (select sum(PurchQty) as cume_PurchQty
      from t t2
      where t2.ProductCode = t.ProductCode and t2.Date <= t.Date
     ) t2
where t2.cume_PurchQty < t.CurrentStock;

在SQL Server 2012+中,使用窗口函数可以更有效地编写它:

select t.*
from (select t.*,
             sum(PurchQty) over (partition by ProductCode order by date) as cume_PurchQty
      from t
     ) t
where cume_PurchQty < CurrentStock

答案 2 :(得分:0)

WebInvoke

答案 3 :(得分:0)

这可以通过使用Rank函数(row_number())轻松实现。我已经使用您的示例输入来填充类似结构的临时表。

create table #tmp
(
ID int, productcode varchar(20), dates date, purchqty int, currstock int
)
insert into #tmp values (1001,'AB101','14-Dec-2016',9,14)
insert into #tmp values (1111,'AB101','01-Jan-2017',18,14)
insert into #tmp values (1223,'AB101','15-Jan-2017',20,14)
insert into #tmp values (1233,'BB400','02-Jan-2017',50,40)
insert into #tmp values (1321,'AB101','31-Jan-2017',8,14)
insert into #tmp values (1400,'BB400','12-Dec-2016',90,40)
insert into #tmp values (1456,'CC200','13-Mar-2017',100,20)


;with CTE AS
(
select *,row_number() over (partition by Diff,productcode order by dates desc) RID 
from (
        select *, case when purchqty-currstock<=0 then 0 else 1 end Diff
        from #tmp  
    )D 
) 
select ID,productCode,dates,purchqty,currstock 
from CTE C1
where (RID=1 and diff=1) OR (Diff=0 and dates >= (select dates from CTE C2 where C2.productcode=C1.productcode and c2.Diff=1 and RID=1))

drop table #tmp