SQL满足以下要求

时间:2016-12-01 08:53:20

标签: sql sql-server sql-server-2012

我有一些数据如下;

select * into #temp from (
select getdate() Dt,20 Qt
union all
select getdate()-1 Dt,70 Qt
union all
select getdate()-1 Dt,20 Qt
union all
select getdate()-2 Dt,50 Qt
union all
select getdate()-4 Dt,40 Qt
union all
select getdate()-4 Dt,80 Qt
union all
select getdate()-6 Dt,20 Qt
) a

此数据表示每次批量生产某些特定日期的产品数量。在任何时候,我只能运送数量< 100并且还基于批次。因此,如果计数超过100,则运输数量超过,输出应如下所示

 date                       QT  shipnum
2016-11-25 03:45:45.897     20  1
2016-11-27 03:45:45.897     40  1
2016-11-27 03:45:45.897     80  2
2016-11-29 03:45:45.897     50  3
2016-11-30 03:45:45.897     70  4
2016-11-30 03:45:45.897     20  4
2016-12-01 03:45:45.897     20  5

可以使用CTE来实现这一目标。如果不是,如何实现这个

2 个答案:

答案 0 :(得分:3)

您使用的是哪个版本?

你能试试这个剧本吗?

SELECT *,SUM(qt)OVER(ORDER BY rn) AS [sum],SUM(qt)OVER(ORDER BY rn)/100+1 AS shipnum FROM (
     SELECT *,ROW_NUMBER()OVER(ORDER BY dt) AS rn FROM #temp
) t
Dt                      Qt          rn                   sum         shipnum
----------------------- ----------- -------------------- ----------- -----------
2016-11-25 17:29:16.280 20          1                    20          1
2016-11-27 17:29:16.280 40          2                    60          1
2016-11-27 17:29:16.280 80          3                    140         2
2016-11-29 17:29:16.280 50          4                    190         2
2016-11-30 17:29:16.280 70          5                    260         3
2016-11-30 17:29:16.280 20          6                    280         3
2016-12-01 17:29:16.280 20          7                    300         4

答案 1 :(得分:0)

使用游标的解决方案 - 请注意我已将日期设置为唯一以简化此示例

/*
drop table #temp
select * into #temp from (
select getdate() Dt,20 Qt, null ino
union all
select getdate()-1 Dt,70 Qt, null ino
union all
select getdate()-2 Dt,20 Qt, null ino
union all
select getdate()-3 Dt,50 Qt, null ino
union all
select getdate()-4 Dt,40 Qt, null ino
union all
select getdate()-5 Dt,80 Qt, null ino
union all
select getdate()-6 Dt,20 Qt, null ino
) a
*/


declare @100 int = 100
declare @rt int = 0
declare @ino int = 1
declare @dt datetime
declare @qt int
declare @rn int

declare sqlcursor cursor for
Select s.qt,s.dt,s.rn
from 
(select t.*, row_number() over (order by t.dt) rn
from #temp t) s

OPEN    sqlcursor 


FETCH NEXT FROM sqlcursor INTO @qt,@dt,@rn  
set @rt = @qt
update #temp set ino = @ino where @dt = #temp.dt


WHILE @@FETCH_STATUS = 0   
BEGIN   
       FETCH NEXT FROM sqlcursor INTO @qt,@dt,@rn  
       IF @@FETCH_STATUS = 0 
        if @rt + @qt > @100 
            begin
                set @ino = @ino + 1
                set @rt = @qt
            end  
        else set @rt = @rt + @qt
        update #temp set ino = @ino where @dt = #temp.dt
END   

CLOSE sqlcursor   
DEALLOCATE sqlcursor

select * from #temp order by dt asc