2014-09-09 2 views
3

행을 테이블에 추가 할 때마다 그 시점까지의 테이블과 비교하여 어디에 순위가 있는지 알고 싶습니다. 이것은 RANK() 윈도우 함수로 쉽게 할 수 있습니다. 그러나, 나는 그 지점까지 테이블과 비교하여 어느 위치에 있는지를 발견하는 방법을 찾고자 애 쓰고있다. 으로 필터링했다. 예를 들어 Redshift : 조건에 따라 필터링 된 행의 순위를 얻으십시오.

, 나는이 매우 인위적인 테이블로 끝날 꿔 :

date | name | animal_bought | num_sloths_bought_before | num_camels_bought_before 
------------+---------+---------------+--------------------------+-------------------------- 
2014-09-01 | Vincent | sloth   | 0      | 0 
2014-09-01 | Luis | camel   | 0      | 0 
2014-09-02 | Vincent | sloth   | 1      | 0 
2014-09-02 | Luis | camel   | 0      | 1 
2014-09-02 | Kevin | sloth   | 0      | 0 
2014-09-03 | Vincent | camel   | 1      | 0 
2014-09-04 | Deo  | camel   | 0      | 0 
2014-09-04 | Vincent | sloth   | 2      | 1 
2014-09-05 | Luis | camel   | 0      | 2 
2014-09-05 | Andrew | sloth   | 0      | 0 
내가 처음에 내가 윈도우 함수에 필터를 적용 할 수 있는지 여부를보고 있었다

(. 예를 들어 RANK() OVER(PARTITION BY name WHERE animal_bought = 'sloth' ORDER BY date ASC) AS num_sloths_bought_before)을하지만, 이것은 구문 상으로 올바르지 않습니다.

SELECT 
    date, 
    name, 
    animal_bought, 
    (SELECT 
     RANK() OVER(PARTITION BY name ORDER BY date ASC) - 1 
    FROM this_table 
    WHERE animal_bought = 'sloth' 
) AS num_sloths_bought_before 
FROM source_table 

하지만 Redshift에이 오류가 발생했습니다 :

ERROR: This type of correlated subquery pattern is not supported yet 

나는 또한 case 문에 윈도우 함수를 넣어 시도했습니다를 (같은 오류가 발생합니다 다음과 같이 나는 다음, 하위 쿼리를 추가하는 시도) 및 조인 쿼리에서 순위를 계산 (작동하지 못하게) 할 수 있습니다.

답변

1

흠. 나는이 쿼리는 어쨌든 원하는 것을 할 것이라고 생각하지 않습니다

SELECT date, name, animal_bought, 
     (SELECT RANK() OVER(PARTITION BY name ORDER BY date ASC) - 1 
     FROM this_table 
     WHERE animal_bought = 'sloth' 
     ) AS num_sloths_bought_before 
FROM source_table 

을 몇 가지 이유를 들어 :

  • rank()의 사용은 animal_bought 일치 this_table에서 하나 개 이상의 행이 있음을 시사한다. 그렇지 않으면 집계 함수를 사용할 수 있습니다.
  • where 절과 일치하는 행이 하나만있는 경우 rank() 전에 where 절이 처리되므로 값은 항상 1입니다.
  • 귀하의 질문은 하나 개의 테이블을 언급하지만 쿼리는

두 아마도 당신은 그냥 부질없는 rank() 원하는가?

SELECT date, name, animal_bought, 
     sum(case when animal = 'sloth' then 1 else 0 end) over (partition by name order by date) as SlothsBefore, 
     sum(case when animal = 'camel' then 1 else 0 end) over (partition by name order by date) as CamelsBefore 
FROM source_table; 

편집 :

SELECT date, name, animal_bought, 
     (sum(case when animal = 'sloth' then 1 else 0 end) over (partition by name order by date) - 
     (case when animal = 'sloth' then 1 else 0 end) 
     ) as SlothsBefore, 
     (sum(case when animal = 'camel' then 1 else 0 end) over (partition by name order by date) - 
     (case when animal = 'camel' then 1 else 0 end) 
     ) as CamelsBefore 
FROM source_table; 
+0

감사, 고든

SELECT date, name, animal_bought, RANK() OVER (PARTITION BY name, animal ORDER BY date ASC) - 1 as NumberBoughtBefore FROM source_table; 

둘 다 동물을 원한다면, rank()를 사용하지 마십시오는 누적 합계를 사용합니다. 불행히도, 그 이름이 각 행에 ** ** 그 행보다 ** 일어난 총 횟수가 아니라 각 행에 동물을 구입 한 총 횟수를 포함하는 표가 생성됩니다. 즉, 빈센트의 모든 행은 행마다 늘어나는 것이 아니라'sloths_bought'에 3을,'camel_bought'에 1을가집니다. – Serenthia

+0

@Serenthia. . . 그냥 1을 빼거나 파티션에서 range/rows 절을 사용하십시오. –

+0

나는''''SUM()'''이 사건이 일어난 모든 시간을 계산하고, 그 사람의 모든 행에 같은 총계를 넣는 것과 같은 결과를 낳을 까봐 두렵습니다. '''''RANK()'''함수에 의해 생성 된 것처럼) 각 행에 다른 번호가 필요합니다. 귀하의 의견을 다시 한번 감사드립니다! – Serenthia

관련 문제