2017-10-17 7 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"열에 있어야합니다.

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

"날짜"로 창을 주문하여 과거 날짜의 "금액 순위"만 계산합니다.

  1. 첫 번째 창 (날짜순) :

    |  Date  | Amount | Product_ID | Rank | 
    |------------------|--------------|------------------|------------| 
    | 2016-01-10 |  7000  |   A  |  1  | 
    
  2. 둘째

    설명

    는 PRODUCT_ID 이상 파티션에 더욱 명확하게 설명하기 Window : 여기에서 두 번째 줄의 크기가 1000보다 작 으면 (d로 정렬 된 Window의 첫 번째 줄의 크기 상기 "등급"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 

이 새로운 코드는 나에게 다음과 같은 결과를 주었다

의 Nota 베네

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 백만 줄의 전체 데이터에서 약간 비싸지 만 작은 덩어리로 데이터를 잘라 내면 그 목표를 달성 할 수 있습니다. –