2016-10-27 6 views
0

次の行から値を取得するSQLの方法を探しています。次の行から値を取得する

私が持っているデータは、次のようになります。

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 +を持っている:私はで終わるために必要なもの

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行を作成したい)があります私はTo_Qtyを作成できるようにこれを行うには、行、および私のETLアプリケーションはSQLではなく、ストアドプロシージャなどができますので、それはSQLにする必要があり

は、どのように私は次の行から値を取得することができますか?

+1

あなたのSQLサーバーのバージョンによっては、 'lead'を使用することができます。テーブルには固有の順序がないので、「次へ」という意味を定義する必要があります。 – HoneyBadger

+0

どのバージョンのSQL Serverを使用していますか? – Lamak

+1

は '鉛を使用してください()'の値は、あなたの方法は、他の問題を導入することなく、問題を解決する理由と方法の説明を含めていただけませんTo_Qty列 –

答えて

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

あなたが言及した結果を生成するためにLEADとFIRST_VALUE分析関数を使用することができます。 LEAD()関数を使用することで、顧客グループ内の次の値を取り出すことができます.FIRST_VALUE()は顧客グループ内の最初の値を返します。

は、例えばのために言います。 CUST = 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]の順序に基づいて次の値を取得します..あなたは[Cust]変更が

値際にリセットするためにPARTITION BY [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と仮定しています。 これで、tempテーブルでupdateステートメントを実行できます。

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) 

そして、もう1つは、存在しない句で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 
関連する問題