2017-10-17 15 views
2

「ランク」をウィンドウの順序で指定されたものとは別の列から計算する方法はありますか?ウィンドウ順序以外の列からRANKを計算するにはどうすればよいですか?

私が何をしたいのかをより明確に説明するために、私は次の例使用します:

データの例は:

|  Date  | Amount | Product_ID | 
|------------------|--------------|------------------| 
| 2016-01-10 |  7000  |   A  | 
| 2016-02-01 |  1000  |   A  | 
| 2016-01-08 |  10000 |   B  | 
| 2016-02-10 |  2000  |   B  | 
| 2016-03-05 |  3000  |   A  | 
| 2016-04-01 |  10000 |   A  | 
| 2016-03-20 |  4000  |   B  | 
| 2016-05-01 |  8500  |   B  | 
| 2016-05-15 |  2000  |   A  | 
|------------------|--------------|------------------| 

問題

したがって、この例で、まず、「Product_ID」でウィンドウを分割して「Date」で注文しますが、計算されたランクは、「Date」列の代わりに「Amount」列にある必要があります。

過去の日付の「金額ランク」のみを計算するように、「日付」でウィンドウを注文したいと考えています。 PRODUCT_ID A以上のパーティションに、もっと明確にそれを説明するために

説明

  1. まずウィンドウ(日付順):

    |  Date  | Amount | Product_ID | Rank | 
    |------------------|--------------|------------------|------------| 
    | 2016-01-10 |  7000  |   A  |  1  | 
    
  2. セカンドウィンドウ:ここでは、2番目の行の量が7000(ウィンドウの最初の行の量はd 、「ランク」は1

    |  Date  | Amount | Product_ID | Rank | 
    |------------------|--------------|------------------|------------| 
    | 2016-01-10 |  7000  |   A  |  1  | 
    | 2016-02-01 |  1000  |   A  |  1  | 
    
  3. サードウィンドウする必要があります)を食べた:上記と同じ論理で、私たちは「ランク」を取得するサブグループ[7000、1000年、3000]で第二位にランクされて2 3000として

    |  Date  | Amount | Product_ID | Rank | 
    |------------------|--------------|------------------|------------| 
    | 2016-01-10 |  7000  |   A  |  1  | 
    | 2016-02-01 |  1000  |   A  |  1  | 
    | 2016-03-05 |  3000  |   A  |  2  | 
    
  4. 第四ウィンドウ:

    |  Date  | Amount | Product_ID | Rank | 
    |------------------|--------------|------------------|------------| 
    | 2016-01-10 |  7000  |   A  |  1  | 
    | 2016-02-01 |  1000  |   A  |  1  | 
    | 2016-03-05 |  3000  |   A  |  2  | 
    | 2016-05-15 |  2000  |   A  |  2  | 
    

それで上記と同じロジック。

私は

を試してみた私はつまり、私が望んで取得するには、次のコードを試してみましたPRODUCT_IDによってパーティションに、日付でウィンドウを注文すると、ランク取る:私は金額順で同じことを試してみた

|  Date  | Amount | Product_ID | Rank | 
|------------------|--------------|------------------|------------| 
| 2016-01-10 |  7000  |   A  |  1  | 
| 2016-02-01 |  1000  |   A  |  2  | 
| 2016-03-05 |  3000  |   A  |  3  | 
| 2016-04-01 |  10000 |   A  |  4  | 
| 2016-05-15 |  2000  |   A  |  5  | 
| 2016-01-08 |  10000 |   B  |  1  | 
| 2016-02-10 |  2000  |   B  |  2  | 
| 2016-03-20 |  4000  |   B  |  3  | 
| 2016-05-01 |  8500  |   B  |  4  | 
|------------------|--------------|------------------|------------| 

SELECT 
      Date, 
      Amount, 
      Product_ID, 
      RANK() OVER(PARTITION BY Product_ID ORDER BY Date) AS Rank 
    FROM Data 

このコードは私に次のような結果を与える

|  Date  | Amount | Product_ID | Rank | 
|------------------|--------------|------------------|------------| 
| 2016-02-01 |  1000  |   A  |  1  | 
| 2016-05-15 |  2000  |   A  |  2  | 
| 2016-03-05 |  3000  |   A  |  3  | 
| 2016-01-10 |  7000  |   A  |  4  | 
| 2016-04-01 |  10000 |   A  |  5  | 
| 2016-02-10 |  2000  |   B  |  1  | 
| 2016-03-20 |  4000  |   B  |  2  | 
| 2016-05-01 |  8500  |   B  |  3  | 
| 2016-01-08 |  10000 |   B  |  4  | 
|------------------|--------------|------------------|------------| 
SELECT 
      Date, 
      Amount, 
      Product_ID, 
      RANK() OVER(PARTITION BY Product_ID ORDER BY Amount) AS Rank 
    FROM Data 

この新しいコードは私に次のような結果を与えました

注意ベネス

N.B.1:私はSQLが基本ですので、スパークSQLでそれを行うことを試みました。 ScalaまたはpySparkを使用した場合の回答も受け入れられます。

N.B.2:これは、スタックオーバーフロー

の私の最初の投稿です、あなたの答えとあなたの理解のためにありがとうございました。

答えて

0

非常に興味深い問題です。あなたは日付ごとの累積ランキングを望んでいるようです。

ウィンドウ関数を使用してこれを行う方法を簡単に考えることはできません。

もちろん
SELECT d.Product_Id, d.Date, d.Amount, 
     SUM(CASE WHEN d2.Amount < d.Amount THEN 1 ELSE 0 END) + 1 as rank 
FROM Data d JOIN 
    Data d2 
    ON d2.Product_Id = d.Product_Id AND 
     d2.Date <= d.Date 
GROUP BY d.Product_Id, d.Date, d.Amount; 

、パフォーマンスがウィンドウ関数アプローチは次のようになりほど良好ではない。ここでは、明示的JOINGROUP BYと方法です。

いくつかのデータベースでは、文字列または配列に量を累積し、次に文字列/配列操作を使用してランクを計算する方法があります。しかし、それでもややこしいかもしれません。

+0

ご回答ありがとうございました、@ Gordon Linoff! それは本当に完璧な仕事です。 私のフルデータは約15百万行ですが、少し高価ですが、データを小さなまとまりにすることで、実現することができます。 –

関連する問題