2016-08-24 1 views
2

나는 다음과 같은 테이블이있는 경우 :특정 값 이전에 얼마나 많은 행이 있었는지 어떻게 계산합니까?

가 난 할 노력하고있어입니다
8, '2016-01-01', FALSE, 
8, '2016-01-04', TRUE, 2 
8, '2016-01-07', FALSE, 
8, '2016-01-09', FALSE, 
8, '2016-01-15', TRUE, 3 
9, '2016-01-05', TRUE, 1 

, 각 C_ID 순서에 의해 :

CREATE TABLE test (
     c_id INTEGER, 
     ref_date DATE, 
     success BOOLEAN 
); 

INSERT INTO test 
VALUES 
(8, '2016-01-01', FALSE), 
(8, '2016-01-04', TRUE), 
(8, '2016-01-07', FALSE), 
(8, '2016-01-09', FALSE), 
(8, '2016-01-15', TRUE), 
(9, '2016-01-05', TRUE) 
; 

내가 다음 반환하는 쿼리를 작성하고 싶습니다를 날짜를 입력 한 다음 success 열의 각 TRUE 값에 대해 해당 c_id 또는 마지막 TRUE 값의 첫 번째 행 이후의 행 수를 계산합니다. 따라서 예제 출력에서 ​​두 번째 행에는 2가 있습니다. 왜냐하면 ref_dates가 정렬 될 때 첫 번째 TRUE 값은 해당 c_id에 대한 그룹 시작 이후의 두 번째 행입니다. 두 번째 행에서 마지막 행까지는 TRUE이고 마지막 TRUE 값 이후의 세 번째 행이기 때문에 3을가집니다.

성공적인 추천을 받기 위해 얼마나 많은 추천을 받았는지 계산하려고합니다.

원래 lag() 윈도우 함수를 사용하여 쿼리를 작성할 수 있다고 생각했지만 성공 속성에 TRUE 값을 가진 마지막 행에 바인드 된 바인딩을 설정할 방법이 없습니다.

특정 값 이전에 얼마나 많은 행이 있었는지 어떻게 계산합니까?

저는 PostgreSQL 9.5를 실행하고 있습니다.

답변

3

나는이 더욱 단순화 할 수있는 느낌이 있지만,이 쿼리를 사용하여 작동합니다

  • lag 플래그에 다른 논리 그룹의 시작 인 행을
  • 누적 sum 모든 태그를 고유 그룹 ID가 동일한 논리 그룹의 행
  • count 그 논리 그룹 ID별로 파티션
,358,쿼리 :
with grp_start_cte as (
    select *, 
     coalesce(lag(success) over (partition by c_id order by ref_date), true) as is_grp_start 
    from test 
), grp_cte as (
    select *, 
     sum(case when is_grp_start then 1 else 0 end) over (partition by c_id order by ref_date) as grp_id 
    from grp_start_cte 
) 
select c_id, ref_date, success, 
     case when success then count(*) over (partition by c_id, grp_id) end as cnt 
    from grp_cte 
order by c_id, ref_date 
+0

lag()의 결과에 대한 sum()이있는 비트가 내 시도가 누락 된 것입니다. 그것은 영리한 작품이었습니다. 도와 줘서 고마워. –

관련 문제