2016-10-28 1 views
2

14 일 롤링 창 내에서 특정 작업 (p.action의 모든 행)을 수행 한 미국 사용자의 수를 찾으려고합니다. , 지난 2 개월 동안.내 하위 선택에서 상관 하위 쿼리를 제거하는 방법 (사전 제한으로 인해)

다음은 쿼리입니다. Presto가 허용하지 않기 때문에 상관 관계가있는 하위 쿼리를 사용하지 않기 위해 다시 작성할 수있는 방법에 대한 몇 가지 팁을 알고 싶습니다.

SELECT dt, 
    (SELECT COUNT(DISTINCT user_id) 
    FROM p.action 
    WHERE dt BETWEEN q.dt - 13 AND q.dt -- period of 14 days 
     AND country = 'US' 
    ) AS 14d_rolling_users 
FROM p.action q 
WHERE dt BETWEEN '2016-08-24' AND '2016-10-24' 
GROUP BY dt 
ORDER BY dt ASC 

는 난 그냥 60 개 개별 쿼리 (매일 하나를) 실행하지 않고이 작업을 수행 할 수있는 방법을 알아 내려고 머리를 건 드리는 있었어요.

도움을 주시면 감사하겠습니다.

답변

1

사전에 경험이 없지만 논리적으로는 동일한 2 개월 날짜 제한을 사용하여 p.action의 두 달 날짜 제한이있는 p.action의 카디 전 곱 조인 (조건없이 조인)을 수행하도록 쿼리를 다시 작성할 수 있습니다. 내부 쿼리가 필요하지 않습니다.

SELECT dt,COUNT(DISTINCT user_id) 
FROM p.action q1,p.action q2 
WHERE q1.dt BETWEEN '2016-08-24' AND '2016-10-24' 
    AND q2.dt BETWEEN '2016-08-24' AND '2016-10-24' 
    AND q1.dt BETWEEN q2.dt - 13 AND q2.dt -- period of 14 days 
    AND country = 'US' 
GROUP BY q1.dt 
ORDER BY q1.dt ASC 

사전에 2 개월 테이블을 만드는 것이 더 효율적입니다. 여기에서 조건은 조인 후에 적용됩니다.

0

0.153 Presto에는 상관 관계가있는 하위 쿼리가 초기 지원됩니다. (https://prestodb.io/docs/current/release/release-0.153.html 참조). 당신은 내가 위의 재 작성이 원래 쿼리보다 더 의미 완전히 다른이 알고 DISTINCT

SELECT dt, 
    (SELECT COUNT(user_id) 
    FROM p.action 
    WHERE dt BETWEEN q.dt - 13 AND q.dt -- period of 14 days 
     AND country = 'US' 
    ) AS 14d_rolling_users 
FROM p.action q 
WHERE dt BETWEEN '2016-08-24' AND '2016-10-24' 
GROUP BY dt 
ORDER BY dt ASC 

를 생략 할 수있는 경우

조회에서 통과해야한다. 그러나 Presto에서 허용되는 사항을 알려주기를 바랍니다. 그러면 원하는 방식으로 쿼리를 다시 작성할 수 있습니다.

어쨌든 나는 그것에 대한 문제를 만들었습니다. 다행히도 곧 수정 될 것입니다. https://github.com/prestodb/presto/issues/6480을 참조하십시오.

0

수동으로 롤백하는 것이 가장 좋습니다.

이렇게하면 표의 각 행이 추가로 rollup__ds 타임 스탬프가있는 14 개의 행으로 바뀝니다. 그런 다음이 새 열을 기준으로 그룹화하여 롤링 14 일짜리 창을 만듭니다. 이것의 복잡성은 O(N*14) = O(N)이며 따라서 선형입니다.

SELECT 
    rollup__ds, 
    COUNT(DISTINCT username) 
FROM (
    SELECT 
    username, 
    ds 
    FROM 
    actions 
    WHERE 
    ds BETWEEN '2016-08-24' AND '2016-10-24' 
    AND country = 'US' 
) 
CROSS JOIN 
    UNNEST(ARRAY[ 
    DATE_ADD('day', 0, CAST(ds AS DATE)), 
    DATE_ADD('day', 1, CAST(ds AS DATE)), 
    ... 
    DATE_ADD('day', 12, CAST(ds AS DATE)), 
    DATE_ADD('day', 13, CAST(ds AS DATE)) 
    ]) AS t (rollup__ds) 
GROUP BY 
    rollup__ds 
ORDER BY 
    rollup__ds 
; 

희망 하시겠습니까?


NB- 그들이 그렇게 합 가능한 있지 않기 때문에이이 고유 한 카운트 작동하지 않습니다 아아 가장, 윈도우 함수를 사용하여 고유 한 카운트가 필요하지 않은 경우.

SELECT 
    ds, 
    -- BEWARE this count is NOT distinct! 
    SUM(COUNT(username)) over (ORDER BY ds ROWS BEWTEEN 13 PRECEDING AND CURRENT ROW) 
FROM 
    actions 
WHERE 
    ds BETWEEN '2016-08-24' AND '2016-10-24' 
    AND country = 'US' 
; 
관련 문제