首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sql server 2008 CTE Bucket填充

sql server 2008 CTE Bucket填充
EN

Stack Overflow用户
提问于 2016-09-09 21:16:56
回答 1查看 66关注 0票数 1

我在下面找到了存储桶填充查询,但是我想将其从使用单个填充器值扩展到能够使用填充器表。请看示例数据查询,所有我想要的是能够连接我的填充表和递归工作,目前我正在从填充物中挑选单个项目。

请看一下这个帖子,了解这个问题的全部背景。http://www.sqlservercentral.com/Forums/Topic568498-338-1.aspx

谢谢。

代码语言:javascript
复制
 DECLARE @Buckets TABLE
     (
       bucketID INT ,
       FullCapacity INT ,
       currentamount INT
     );

 DECLARE @Filler TABLE ( ID INT, Filler INT );

 INSERT  INTO @Buckets
 VALUES  ( '1', 85, 0 ) ,
         ( '2', 80, 0 ) ,
         ( '3', 75, 0 ) ,
         ( '4', 70, 0 ) ,
         ( '5', 50, 0 ) ,
         ( '6', 40, 0 );

 INSERT  INTO @Filler
 VALUES  ( '1', 90 ) ,
         ( '2', 40 ) ,
         ( '3', 70 ) ,
         ( '4', 50 ) ,
         ( '5', 40 ) ,
         ( '6', 30 ) ,
         ( '7', 35 );

 DECLARE @AmountToAllocate INT = ( SELECT TOP 1
                                             Filler
                                   FROM      @Filler
                                 );
 --single filler amount
 ;WITH    Calculator
           AS ( SELECT   bucketID ,
                         FullCapacity ,
                         currentamount ,
                         AmountLeftToAllocate = CASE WHEN @AmountToAllocate > ( FullCapacity
                                                               - currentamount )
                                                     THEN @AmountToAllocate
                                                          - ( FullCapacity
                                                              - currentamount )
                                                     WHEN @AmountToAllocate < 0
                                                          AND ABS(@AmountToAllocate) > currentamount
                                                     THEN currentamount
                                                          + @AmountToAllocate
                                                     ELSE 0
                                                END ,
                         NewAmount = CASE WHEN @AmountToAllocate > ( FullCapacity
                                                               - currentamount )
                                          THEN FullCapacity
                                          WHEN @AmountToAllocate < 0
                                               AND ABS(@AmountToAllocate) > currentamount
                                          THEN 0
                                          ELSE currentamount
                                               + @AmountToAllocate
                                     END
                FROM     @Buckets
                WHERE    bucketID = 1
                UNION ALL
                SELECT   tr.bucketID ,
                         tr.FullCapacity ,
                         tr.currentamount ,
                         AmountLeftToAllocate = CASE WHEN lr.AmountLeftToAllocate > ( tr.FullCapacity
                                                               - tr.currentamount )
                                                     THEN lr.AmountLeftToAllocate
                                                          - ( tr.FullCapacity
                                                              - tr.currentamount )
                                                     WHEN lr.AmountLeftToAllocate < 0
                                                          AND ABS(lr.AmountLeftToAllocate) > tr.currentamount
                                                     THEN tr.currentamount
                                                          + lr.AmountLeftToAllocate
                                                     ELSE 0
                                                END ,
                         NewAmount = CASE WHEN lr.AmountLeftToAllocate > ( tr.FullCapacity
                                                               - tr.currentamount )
                                          THEN tr.FullCapacity
                                          WHEN lr.AmountLeftToAllocate < 0
                                               AND ABS(lr.AmountLeftToAllocate) > tr.currentamount
                                          THEN 0
                                          ELSE tr.currentamount
                                               + lr.AmountLeftToAllocate
                                     END
                FROM     @Buckets tr
                         INNER JOIN Calculator lr ON lr.bucketID + 1 = tr.bucketID
              )
     SELECT  bucketID ,
             FullCapacity ,
             Amount = NewAmount ,
             OldAmount = currentamount
     FROM    Calculator;
EN

回答 1

Stack Overflow用户

发布于 2016-09-13 17:43:54

在SQL 2012中,但仍在尝试在SQL 2008中找到解决方案。

代码语言:javascript
复制
DROP TABLE #Buckets
CREATE TABLE #Buckets (bucketID INT, FullCapacity INT, CurrentAmount INT);
INSERT INTO #Buckets
VALUES  ( '1', 85, 0 ) ,
         ( '2', 80, 0 ) ,
         ( '3', 75, 0 ) ,
         ( '4', 70, 0 ) ,
         ( '5', 50, 0 ) ,
         ( '6', 40, 0 );

DROP TABLE #Filler
CREATE TABLE #Filler (FillerID INT, Filler INT); 
INSERT INTO #Filler
VALUES  ( '1', 90 ) ,
         ( '2', 40 ) ,
         ( '3', 70 ) ,
         ( '4', 50 ) ,
         ( '5', 40 ) ,
         ( '6', 30 ) ,
         ( '7', 35 );

WITH ProcessedDebits AS (  
    SELECT bucketID, FullCapacity, [from] = ([to] - FullCapacity), [to]
    FROM (SELECT *, [to] = SUM(FullCapacity) OVER (PARTITION BY 1 ORDER BY bucketID 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM #Buckets) d
),
ProcessedCredits AS (  
    SELECT FillerID, Filler, [from] = ([to] - Filler), [to]
    FROM (SELECT *, [to] = SUM(Filler) OVER (PARTITION BY 1 ORDER BY FillerID 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM #Filler) d
)

SELECT 
    bucketID, FullCapacity, 
    DebitBalance = CASE 
        WHEN dr.[to] >= cr.[to] THEN (dr.[to] - cr.[to]) 
        WHEN dr.[to] <  cr.[to] THEN 0
        ELSE dr.[to] - MAX(cr.[to]) OVER(PARTITION BY 1 ORDER BY dr.bucketID 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
            END,
    FillerID, Filler,  
    CreditBalance = CASE 
        WHEN cr.[to] >= dr.[to] THEN (cr.[to] - dr.[to]) 
        WHEN cr.[to] <  dr.[to] THEN 0 
        ELSE cr.[to] - MAX(dr.[to]) OVER(PARTITION BY 1 ORDER BY cr.FillerID 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
            END
FROM ProcessedDebits dr
FULL OUTER JOIN ProcessedCredits cr
    ON cr.[from] < dr.[to] 
    AND cr.[to] > dr.[from] 
ORDER BY bucketID, FillerID
OPTION (MAXDOP 1);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39412466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档