2014-06-05 5 views
2

테이블 daily_user의 샘플 데이터가 있습니다. 각 행은 특정 날짜의 활성 사용자를 나타내며 수익은 해당 날짜에 사용자가 생성 한 금액을 기반으로합니다. 이 표의 가장 빠른 날짜는 1/1입니다.하이브의 누적 고유 카운트

date user_id group revenue 
1/1 1  a  1 
1/1 2  b  0 
1/1 3  a  0 
1/2 2  b  10 
1/2 3  a  0 
1/3 3  a  1 

나는 기본적으로 각 행. 1/1에서 지금까지 지불 한 얼마나 많은 사용자가 각각의 관찰 일에, 각 그룹에 대해 알려줍니다 예를 들어, 마지막 행에서 의미 (원하는 출력 1/1 1/3, 그룹 B의 총에서 우리는 우리를 지불 한 사용자)이 있습니다

end_date group  # users who ever paid 
1/1   a    1 
1/1   b    0 
1/2   a    1 
1/2   b    1 
1/3   a    2 
1/3   b    1 

누적 합계를 할 수있는 몇 가지 UDF에있는 것 같다,하지만 난 어떤 누적 고유 한 카운트 기능이 있는지 확실하지 않다 내가 여기서 활용할 수있는 것. 어쨌든 이것을 구현하기 위해 하이브 쿼리를 구조화 할 수 있습니까?

+0

누적 * 별개 * 수 또는 누적 할인 수를 의미합니까? –

+0

뚜렷한 의미, 감사합니다! – tonystarkix

답변

0

수익이 0이면 함수 if(revenue=0,1,0)은 값 1을 가지며 그렇지 않으면 값 0을 갖습니다. 이 기능을 합산하면 0의 수익을했다 사람의 총 수를 줄 것이다 :

select 
    date as end_date, 
    group, 
    sum(if(revenue=0,1,0)) as number_of_users_who_never_paid 
from 
    daily_user 
group by 
    date, 
    group 
+0

제이슨 감사합니다. 실제로 누적 지급기 수를 얻는 데 더 많은 관심이 있습니다. – tonystarkix

2

나는이 솔루션은 실제로 'collect_set'사용자가 (고유 한 값을 수집) 및 배열의 ​​크기를 취할 생각 사용자의 작은 숫자 (예. 메모리에 딱 맞는) 순 많은 수의 들어

SELECT size(collect_set(user_id)) as uniques 
     end_date, group 
FROM daily_user 
GROUP BY end_date, group; 

, 당신은 (http://github.com/klout/brickhouse를 UDF 년대 Brickhouse 라이브러리로 사용할 스케치 세트 또는 hyperloglogs, 같은 확률 데이터 구조를해야합니다). 그 이전 일로부터 미리 계산 된 컬렉션/스케치를 병합 할 수 있도록이 당신에게 가까운 견적을 제공하지만, 유니크

SELECT estimated_reach(sketch_set(user_id)) as uniques_est, 
     end_date, group 
FROM daily_user 
GROUP BY end_date, group; 

또한 다음을 병합 할 수 있습니다 아닌 정확한 수 있습니다. 뭔가 같이 :

SELECT size(combine_unique(unique_set)) as uniques, 
     group 
FROM daily_uniques 
WHERE end_date > date_add(today, -30) 
GROUP BY group; 

또는

SELECT estimated_reach(union_sketch(unique_sketch)) as uniques, 
     group 
FROM daily_uniques 
WHERE end_date > date_add(today, -30) 
GROUP BY group; 
0

사용자 정의 UDF를 작성하지 않고,이를위한 가장 간단한 방법은, 직교 어떤 종류의 작업을 수행하는 것입니다 가입 :

select 
    date as end_date, 
    group, 
    sum(if(mon.user_id is not null AND mon.date <= du.date,1,0)) as cumulative_spenders 
from 
    daily_user du 
LEFT OUTER JOIN 
    (
    select 
    distinct 
    user_id, 
    date, 
    group 
    from 
    daily_user 
    where 
    revenue > 0 
    ) mon 
ON 
    (du.user_id=mon.user_id and du.group=mon.group) 
group by 
    date, 
    group  

이 의지 원래 테이블의 항목 당 지출 트랜잭션 당 행을 생성 한 다음 거기에서 집계하십시오.

+0

내가 틀렸다고 정정하면 각 사용자마다 cumulative_spenders가 고유합니까? 그것은 user_id 1 쿼리 결과에 여전히 여러 행을 것 같다 – tonystarkix

+0

예, 사실입니다 - 문제를 해결해야한다 구별을 추가했습니다 –