2016-10-27 25 views
0

我正在尋找一個SQL的方式來獲得從下一行的值。SQL GET值由下一行

我的數據是這樣的:

CUST PROD  From_Qty Disc_Pct 
23  Brush 1   0 
23  Brush 13   1 
23  Brush 52   4 
77  Paint 1   0 
77  Paint 22   7 

我需要與最終是這樣的,(我想創建To_Qty行):

CUST PROD  From_Qty To_Qty Disc_Pct 
23  Brush 1   12  0 
23  Brush 13   51  1    #13 is 12+1 
23  Brush 52   99999  4    #52 is 51+1 
77  Paint 1   21  0    #1 is 99999+1 
77  Paint 22   99999  7    #22 is 21+1 

我有100K +行這樣做是爲了和它必須是SQL,因爲我的ETL應用程序允許SQL而不是存儲過程等

如何從下一行中獲得的價值,所以我可以創建To_Qty?

+1

根據您的SQL Server版本,你可以使用'lead'。您確實需要定義「下一步」的含義,因爲表格沒有固有的順序。 – HoneyBadger

+0

您使用的是哪個版本的SQL Server? – Lamak

+1

使用'lead()'函數 –

回答

0
SELECT 
CUST, 
PROD, 
FROM_QTY , 
COALESCE(MIN(FROM_QTY) OVER (PARTITION BY CUST, PROD ORDER BY FROM_QTY DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) , 10000)-1, 
DISC_PCT 
FROM <tablename> 
ORDER BY CUST, PROD, FROM_QTY 
+2

您是否介意解釋爲什麼以及您的方法如何解決問題而不引入其他問題? –

+0

這是完美的!它將客戶和產品都考慮在內,並且像魅力一樣起作用。謝謝!!!!!!!! :) – RobB

1

如果您正在運行SQL Server 2012或更高版本,可以使用LAG和LEAD函數與當前行一起訪問之前或之後的行。

0

您可以使用鉛和FIRST_VALUE解析函數生成你提到的結果。通過使用LEAD()函數,可以檢索客戶組中的下一個值,FIRST_VALUE()將爲客戶組提供第一個值。

說的如。用戶值= 23 ... LEAD將返回13 FIRST_VALUE返回1 ... TO_QTY = LEAD - FIRST_VALUE即.. 13-1 = 12。以類似的方式,下面提到的公式將計算表中所有100k行。

SELECT CUST, 
      PROD, 
      FROM_QTY, 
      CASE WHEN LEAD(FROM_QTY,1) OVER (PARTITION BY CUST ORDER BY FROM_QTY) IS NOT NULL 
       THEN 
      LEAD(FROM_QTY,1) OVER (PARTITION BY CUST ORDER BY FROM_QTY) - 
FIRST_VALUE(FROM_QTY) OVER (PARTITION BY CUST ORDER BY FROM_QTY) 
       ELSE 99999 
      END AS TO_QTY, 
      DISC_PCT 
     FROM Yourtable; 
1
SELECT *, 
     LEAD([From_Qty], 1, 100000) OVER (PARTITION BY [CUST] ORDER BY [From_Qty]) - 1 AS To_Qty 
FROM myTable 

LEAD()將讓你根據的[From_Qty]訂單上的下一個值..你用PARTITION BY [CUST][Cust]變化值

重置或者您可以使用一個CTE和ROW_NUMBER 。

WITH cte AS 
(
    SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY [CUST] ORDER BY [From_Qty]) Rn 
    FROM myTable 
) 
SELECT t1.*, 
     ISNULL(t2.From_Qty - 1, 99999) To_Qty 
FROM cte t1 
     LEFT JOIN cte t2 ON t1.Cust = t2.Cust AND t1.Rn + 1 = t2.Rn 
0

將數據插入到具有相同列但添加了id自動增加字段的臨時表中。插入他們訂購,我通過cust,prod,然後from_qty假設。 現在您可以在臨時表上運行更新語句。

UPDATE #mytable 
SET To_Qty = (SELECT From_Qty - 1 FROM #mytable AS next WHERE next.indexfield = #mytable.indexfield + 1 AND next.cust = #mytable.cust and next.prod = #mytable.prod) 

然後再用另一個做不存在的子句99999。

然後將數據插回到新的或修改的表格中。

0
declare @Table table(CUST int, PROD varchar(50), From_Qty int, Disc_Pct int) 
insert into @Table values 
(23, 'Brush', 1,  0) 
,(23, 'Brush', 13,  1) 
,(23, 'Brush', 52,  4) 
,(77, 'Paint', 1,  0) 
,(77, 'Paint', 22,  7) 

SELECT CUST, Prod, From_qty, 
     LEAD(From_Qty,1,100000) OVER(PARTITION BY cust ORDER BY from_qty)-1 AS To_Qty, 
     Disc_Pct 
    FROM @Table