2016-09-09 4 views
1

Я нашел ниже запрос заполнения заполнителя, однако я хочу расширить его, используя одно значение заливки, чтобы использовать таблицу наполнителя. Пожалуйста, см. Запрос с образцом данных, все, что я хочу, чтобы присоединиться к моей таблице заполнителя и рекурсии для работы, как есть, в настоящее время я выбираю один элемент из наполнителя.sql server 2008 CTE Bucket fill

Пожалуйста, взгляните на эту тему, чтобы иметь полный контекст этой проблемы. http://www.sqlservercentral.com/Forums/Topic568498-338-1.aspx

спасибо.

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; 

ответ

0

В SQL 2012, но все еще пытается найти решение в SQL 2008.

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); 
Смежные вопросы