我正在寻找的输出是每个日期的记录,包括DISTINCT活跃成员的数量和DISTINCT Rolling 7天活跃成员的数量。
我正在使用两个表 - [transactions],它们通过我们的系统记录每笔交易,包括交易处理日期的dmn_date_id,以及DATE_DIMENSION,它在1990年到2020年之间每天都有,day_offset_nbr代表从TODAY()偏移的天数(此表每晚重建)。
SELECT
dd.date_tms
, COUNT(DISTINCT(t.user_id)) as Active_Members_Today
, COUNT(DISTINCT(t2.user_id)) as Rolling_7Day_Active_Members
FROM
transactions t
JOIN DATE_DIMENSION dd
ON t.transaction_processed_date_id = dd.date_id
JOIN DATE_DIMENSION d2
ON d2.day_offset_nbr BETWEEN (dd.day_offset_nbr - 6) AND dd.day_offset_nbr
JOIN transactions t2
ON d2.dmn_date_id = t2.common_trans_processed_date_id
WHERE
t.user_initiated_ind = 'Y' -- Only User-initiated Transactions
AND t2.user_initiated_ind = 'Y'
AND t.transaction_state_name = 'Accepted' -- Accepted Transactions Only
AND t2.transaction_state_name = 'Accepted'
AND dd.day_offset_nbr >= -731
AND d2.day_offset_nbr >= -738
GROUP BY
dd.date_tms
上面的查询得到了我们需要的东西,但需要花费很长时间(超过一小时)来处理。我们已经在user_initiated_ind和common_trans_processed_date_id上创建了索引,包括user_id,但查询仍在消失。
以为我可以通过窗口函数解决这个问题,据悉你不能在窗口中使用DISTINCT,这导致我使用带有Row_Number()的派生表来识别窗口内的DISTINCT用户,这让我发现Row_Number()不能与Window ...中的ROWS BETWEEN子句一起使用
我读过Calculate running total / running balance这是类似的,但处理的是运行平衡,而不是滚动不同的计数,我不太确定如何应用我读到的问题;只是我正在使用的INNER JOIN方法被建议不是使用的方法......
......这激励我发帖。
如何改善查询效果?
答案 0 :(得分:1)
第二次加入transactions
似乎完全没必要。您可以使用条件聚合进行计数。所以,这个版本可能会更快:
SELECT d2.date_tms,
count(distinct case when d2.day_offset_nbr = dd.day_offset_nbr then t.user_id end) as Active_Members_Today,
count(distinct t.user_id) as Rolling_7Day_Active_Members
FROM transactions t JOIN
DATE_DIMENSION dd
ON t.transaction_processed_date_id = dd.date_id JOIN
DATE_DIMENSION d2
ON d2.day_offset_nbr BETWEEN dd.day_offset_nbr AND (dd.day_offset_nbr + 6) AND
WHERE t.user_initiated_ind = 'Y' AND -- Only User-initiated Transactions
t.transaction_state_name = 'Accepted' AND -- Accepted Transactions Only
dd.day_offset_nbr >= -731
GROUP BY d2.date_tms;