2014-02-12 51 views
4

表1:巢式病例

ARTIKEL  SUPPLIERID SALE_SUM_PIECES 
TV   SONY   7    

TABLE2:

ROW_ID  ARTIKEL  SUPPLIERID  PIECES  
    1   TV   SONY  6  
    2   TV   SONY  10  
    3   TV   SONY  6  
    4   TV   SONY  14  
    5   TV   SONY  18  
    6   TV   SONY  4 

我需要在TABLE2."PIECES"減去價值X=23,價值TABLE1只有當 「SALE_SUM_PIECES」 小於「的總和。 PIECES「在表2中。例如:TABLE1."SALE_SUM_PIECES"的值是7。 NOw我需要檢查在哪一行的值7 goes less than SUM的TABLE2."PIECES"。在以下示例中,TABLE2中的第一行無效,因爲7大於6.但TABLE2中的第二行是有效的,因爲「PIECES」從TABLE2中的row1和row2即6 + 10 = 16大於7.因此,我需要從TABLE2的第二行減去X=23的值到以下行。 查詢我有如下:

SELECT "SUPPLIERID", "ARTIKEL", 
    (case when (cumulativesum - (select "SALE_SUM_PIECES" from T1 where T1."SUPPLIERID"=T2."SUPPLIERID" and T1."ARTIKEL" = T2."ARTIKEL")) <= 0 
     then NULL 
     when (cumulativesum - (select "SALE_SUM_PIECES" from TABLE1 T1 where T1."SUPPLIERID"=T2."SUPPLIERID" and T1."ARTIKEL" = T2."ARTIKEL")) > 0 
     then 
      (case when @x - cumulativesum <= 0 and @x - (cumulativesum -PIECES) > 0 
       then 0 
       when @x - "cumulativesum" <= 0 
       then NULL 
       else @x - "cumulativesum" 
      end) as "VALUE_DRILL_DOWN" 
    from (SELECT T1."ARTIKEL", T1."SUPPLIERID", T1.PIECES 
      (select sum("PIECES") 
       from EXAMPLE_TABLE T2 
       where T2."ROW_ID" <= T1."ROW_ID" and T2."SUPPLIERID" = T1."SUPPLIERID" and T2."ARTIKEL"=T1."ARTIKEL" 
      ) as "cumulativesum" 
    from EXAMPLE_TABLE T1 
    ) 

當我執行上面的查詢,我得到的結果如下:

ROW_ID  ARTIKEL  SUPPLIERID PIECES  VALUE_DRILL_DOWN 
    1   TV   SONY  6   NULL 
    2   TV   SONY  10   7 
    3   TV   SONY  6   1 
    4   TV   SONY  14   0 
    5   TV   SONY  18   Null 
    6   TV   SONY  4   Null 

但我期待有一個結果如下:

ROW_ID  ARTIKEL  SUPPLIERID PIECES VALUE_DRILL_DOWN 
    1   TV   SONY   6   NULL 
    2   TV   SONY   10   13 
    3   TV   SONY   6   7 
    4   TV   SONY   14   0 
    5   TV   SONY   18   Null 
    6   TV   SONY   4   Null 

我想減去'X = 23'從TABLE2中的行開始,其中條件TABLE1."SALE_SUM_PIECES" < TABLE2."PIECES"即從row2開始。有什麼建議麼?

在此先感謝。

+0

在BZBAS_AW在T2什麼樣的價值觀?爲T2提供的值也請參見 – NickyvV

+0

@NickyvV BZBAS_AW不過是結果表中的'PIECES' –

+0

@NickyvV我已經對該問題進行了編輯。對不起,我的錯。 –

回答

1

下面的解決方案給出了預期的結果。見SqlFiddle

1 TV SONY 922 6 110 2.50 NULL 
2 TV SONY 922 10 80 1.00 13 
3 TV SONY 922 6 65 1.50 7 
4 TV SONY 922 14 95 1.50 0 
5 TV SONY 922 18 95 1.50 NULL 
6 TV SONY 922 4 95 1.50 NULL 



DECLARE @x INT = 23 

; WITH cte AS 
(
    SELECT t2.*, t1.SALE_SUM_PIECES, 
      CASE 
       WHEN SUM(t2.PIECES) OVER (PARTITION BY t2.ARTIKEL, t2.SUPPLIERID ORDER BY ROW_ID) < t1.SALE_SUM_PIECES THEN 'None' 
       ELSE t2.ARTIKEL + t2.SUPPLIERID 
      END AS GroupId 
    FROM @Table2 t2 
    JOIN @Table1 t1 ON t2.ARTIKEL = t1.ARTIKEL AND t2.SUPPLIERID = t1.SUPPLIERID 
), 
cumulative AS 
(
    SELECT *, SUM(PIECES) OVER (PARTITION BY GroupId ORDER BY ROW_ID) AS CumulativeSum 
    FROM cte 
) 
SELECT ROW_ID, ARTIKEL, SUPPLIERID, ORGID, PIECES, COSTPRICE, DISCOUNT, 
     CASE 
      WHEN CumulativeSum < SALE_SUM_PIECES THEN NULL 
      WHEN @x - CumulativeSum <= 0 AND @x - (CumulativeSum - PIECES) > 0 THEN 0 
      WHEN @x - CumulativeSum <= 0 THEN NULL 
      ELSE @x - CumulativeSum 
     END AS VALUE_DRILL_DOWN 
FROM cumulative 
+0

這很有效。我現在有了一個想法。謝謝大家的努力。我衷心感謝您的支持。乾杯 –

1

我不是100%確定VALUE_DRILL_DOWN應該是什麼樣的期望值。 你已經說過對於一個有效的行,它應該是(在行或行上的所有行的總和) - 23

在這種情況下,下面的代碼應該可以工作,但它會給出與預期結果不同的數字。

我已經使用了一個自加入公共表表達式來計算行數的累計和。

的(總處於或高於所有行的)等於(總) - (在以前的行累積和)

因此下面的代碼是正確...

DECLARE @table1 TABLE(ARTIKEL NVARCHAR(50), SUPPLIERID NVARCHAR(50), ORGID INT, 
STORE INT, SALE_SUM_PIECES INT, [DATE] DATETIME) 
DECLARE @table2 TABLE(ROW_ID INT, ARTIKEL NVARCHAR(50), SUPPLIERID NVARCHAR(50), 
ORGID INT, PIECES INT, COSTPRICE MONEY, DISCOUNT DECIMAL(9,5)) 
DECLARE @x INT = 23 
DECLARE @SumOfAll INT 
INSERT @table1 
     (ARTIKEL , SUPPLIERID , ORGID , STORE , SALE_SUM_PIECES , [DATE]) 
VALUES ('TV', 'SONY', 922,100,7 ,'2014-01-01' ) 
INSERT @table2 
     (ROW_ID, ARTIKEL , SUPPLIERID , ORGID , PIECES , COSTPRICE , DISCOUNT ) 
VALUES (1, 'TV', 'SONY', 922, 6, 110, 2.5), 
    (2, 'TV', 'SONY', 922, 10 , 80, 1) , 
    (3, 'TV', 'SONY', 922, 6 , 65 , 1.5 ) , 
    (4, 'TV', 'SONY', 922, 14 , 95 , 1.5 ), 
    (5, 'TV', 'SONY', 922, 18 , 95 , 1.5 ), 
    (6, 'TV', 'SONY', 922, 4 , 95 , 1.5 ) 

SELECT @SumOfAll = SUM(PIECES) FROM @table2 AS t 

;WITH t2C AS (
    SELECT ROW_ID, PIECES AS [cumulativeSum] 
    FROM @table2 AS t 
    WHERE ROW_ID = 1 -- assume starting at 1 
    UNION ALL 
    SELECT t.ROW_ID, t.PIECES + cumulativeSum AS [cumlativeSum] 
    FROM @table2 AS t 
    JOIN t2C ON t2C.ROW_ID + 1 = t.ROW_ID --assume rowIDs are sequential 
) 
SELECT 
    t2.ROW_ID, 
    t1.SUPPLIERID, 
    t1.ORGID, 
    t2.PIECES, 
    t2.COSTPRICE, 
    t2.DISCOUNT, 
    CASE WHEN t2C.cumulativeSum - t1.SALE_SUM_PIECES <= 0 THEN NULL 
     ELSE 
      CASE 
       WHEN @x - t2C.cumulativeSum <= 0 
        AND @x - (t2C.cumulativeSum - t2.PIECES) > 0 THEN 0 
       WHEN @x - t2C.cumulativeSum <= 0 THEN NULL 
       ELSE (@SumOfAll - t2cPrev.cumulativeSum) - @x 
      END 
     END AS [VALUE_DRILL_DOWN] 
FROM t2C 
LEFT JOIN t2C AS t2cPrev ON t2cPrev.ROW_ID = t2C.ROW_ID - 1 
JOIN @table2 AS t2 ON t2.ROW_ID = t2C.ROW_ID 
JOIN @table1 AS t1 ON t1.SUPPLIERID = t2.SUPPLIERID AND t1.ARTIKEL = t2.ARTIKEL 

但是這給:

ROW_ID SUPPLIERID ORGID PIECES COSTPRICE DISCOUNT VALUE_DRILL_DOWN cumulativeSum sumOfRowsOnOrAfter 
1  SONY  922  6  110.00  2.50000  NULL    6    NULL 
2  SONY  922  10  80.00  1.00000  29     16    52 
3  SONY  922  6  65.00  1.50000  19     22    42 
4  SONY  922  14  95.00  1.50000  0     36    36 
5  SONY  922  18  95.00  1.50000  NULL    54    22 
6  SONY  922  4  95.00  1.50000  NULL    58    4 

編輯:

SQL Fiddle by WiiMaxx

+0

這裏的[sqlfiddle](http://sqlfiddle.com/#!6/82534/1)爲他的答案 – WiiMaxx

0
select 
    *, 
    case when 23 - sum(c) over (order by row_id) >= 0 
     then 23 - sum(c) over (order by row_id) 
     when 23 - sum(c) over (order by row_id) + pieces > 0 
     then 0 
    end value_drill_down 
from (
     select *, 
     case when sum(pieces) over (order by row_id) >= (select sale_sum_pieces from t1) 
       then pieces 
     end c 
     from t2) x;