2017-11-27 1 views
1

표준 SQL BigQuery에서 FILTER (http://modern-sql.com/feature/filter)의 동작을 에뮬레이트 할 수있는 방법이 있습니까? 내가 할 필요가 무엇BigQuery에서 이벤트 최신 성을 계산하는 윈도우의 필터 파티션

은 다음과 같습니다 본질적으로

SELECT MAX(date) FILTER (WHERE event_happend = 1) OVER ( PARTITION BY user_id ORDER BY date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM ...

내가 어떤 이벤트가 현재 행의 날짜 이전에 발생한 가장 최근의 날짜를 해결해야합니다. 열 event_happened의 값은 0 및 이며, 현재 행의 날짜 이전에 이벤트가 발생한 가장 최근 날짜가 필요합니다 (event_happened = 1).

+0

왜 ROWS 대신 RANGE를 사용합니까? 그런 다음 현재 행의 값을 제외 할 수 있습니다. –

+0

@ElliottBrossard 제안 해 주셔서 감사합니다. 그러나 RANGE를 사용하는 것이 어떻게 도움이되는지 잘 모르겠습니다. 제발 좀 더 자세히 설명해 주시겠습니까? 나는 또한 명확하게하기 위해 나의 질문에 다음을 추가했다 : "열 event_happened 값을 0과 1이 소요되며 event_happened = 1 현재 행의 날짜 이전에 이벤트가 발생한 가장 최근 날짜가 필요합니다." – user3531907

+0

@ElliottBrossard 또한 질문에 날짜 열의 이름을 업데이트했습니다. 당연히 혼란 스러웠습니다. – user3531907

답변

1

FILTER의 동작을 에뮬레이션 할 수있는 방법이 있습니까?

#standardSQL 
SELECT 
    MAX(IF(event_happend = 1, date, null)) 
    OVER (
    PARTITION BY user_id 
    ORDER BY date ASC 
    ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING 
) 
    FROM 
    ... 
+0

창에 동일한 '날짜'값이 여러 개 있으면 잠재적으로 잘못된 대답을 줄 수 있습니다. 내 해결 방법을 참조하십시오. 'RANGE'. –

+0

: o) 'MAX (IF (event_happend = 1, date, null))'는 'FILTER'에 대한 답변의 핵심입니다. OP로 예상되는 정확한 논리가 명확하지 않으므로 원래 질문에서 다른 것을 수정하지 않았습니다. –

+0

나는 동의한다. 그러나 OP는 "현재 행의 날짜 이전에"진술했다. 그래서 그것을 고려하는 것이 중요 해 보였다. –

2

이 시도 :

#standardSQL 
WITH SampleData AS (
    SELECT 1 AS user_id, DATE '2017-11-02' AS date, 1 AS event_happend UNION ALL 
    SELECT 1, DATE '2017-11-03', 0 UNION ALL 
    SELECT 1, DATE '2017-11-04', 1 UNION ALL 
    SELECT 1, DATE '2017-11-04', 1 UNION ALL 
    SELECT 1, DATE '2017-11-05', 0 UNION ALL 
    SELECT 2, DATE '2017-11-10', 1 UNION ALL 
    SELECT 2, DATE '2017-11-11', 0 UNION ALL 
    SELECT 2, DATE '2017-11-20', 0 UNION ALL 
    SELECT 2, DATE '2017-11-21', 1 
) 
SELECT 
    user_id, 
    date, 
    MAX(IF(event_happend = 1, date, NULL)) OVER (
    PARTITION BY user_id ORDER BY UNIX_DATE(date) 
    RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING 
) AS max_date 
FROM SampleData; 

내가 무슨 일이 일어나고 있는지 볼 수 user_iddate 포함되어 있습니다. 여기에 RANGE을 사용하는 것이 중요합니다. ROWS을 사용하는 경우 창의 이전 행에 동일한 date 값이있을 수 있습니다. RANGE1 PRECEDING과 함께 사용하면 창의 모든 행에 현재보다 작은 date 값이 적용되도록 할 수 있습니다.

관련 문제