如何提取在 2020 年 1 月至少访问过两次但未进行交易的所有 visitor_id 的列表(在他们 1 月的任何一次访问中)
Posted
技术标签:
【中文标题】如何提取在 2020 年 1 月至少访问过两次但未进行交易的所有 visitor_id 的列表(在他们 1 月的任何一次访问中)【英文标题】:How to pull a list of all visitor_ids that have visited at least twice in January 2020, but did not transact (in ANY of their January visits) 【发布时间】:2020-05-18 00:58:58 【问题描述】:表格:
会话
session_ts visitor_id 垂直 session_id交易
session_ts session_id rev_bucket 收入目前有以下查询(使用 SQLite):
SELECT
visitor_id,
session_id,
running_total
FROM
(
SELECT
s.visitor_id,
s.session_id,
t.revenue,
ROW_NUMBER() OVER(PARTITION BY s.visitor_id ORDER BY t.session_ts) as row_num,
SUM(revenue) OVER(PARTITION BY s.visitor_id) as running_total
FROM sessions s
JOIN transactions t
ON s.session_id = t.session_id
WHERE s.session_ts >= '2020-01-01' AND s.session_ts < '2020-02-01'
) sub
Where running_total = 0
AND row_num >= 2
样本表的结果:
欢迎任何反馈,在此先感谢。不确定上述查询是否是正确答案。还想知道我是否也可以像这样显示每个 visitor_id 的单个 session_id:
【问题讨论】:
如果没有事务是要求的一部分,那么内部连接就不能工作。 如果“无事务”意味着 $0 并且仍然记录 session_id,那么内部连接会起作用吗?另外,我的查询是否可以识别“无交易”? 【参考方案1】:我假设会话是访问。那就是:
select s.visitor_id
from sessions s
where s.session_ts >= '2020-01-01' and s.session_ts < '2020-02-01' and
not exists (select 1
from transactions t
where t.session_id = s.session_id
)
group by s.visitor_id
having count(*) >= 2;
【讨论】:
很好的建议,效果很好。如果我不得不假设“没有交易”意味着 $0 并且仍然记录了 session_id,我的查询会起作用吗? @KevinKung 。 . .我不明白你的评论是什么意思。您可以调整not exists
逻辑来比较特定类型的交易,例如金额大于零的交易。【参考方案2】:
如果没有负面交易,它会起作用,只是您没有在“运行总数”中添加order by
,因此您需要修复它。虽然您在别名中将其称为运行总计,但它根本没有真正运行。不确定这是否是关于命名或实现的混淆。如果您以相反的顺序按美元排序,那么您将走在正确的轨道上,以便首先出现非零行,这样当您到达第二行并且运行总数仍然为零时,那么该访问者确实必须符合条件。但这有点绕道。
为了让访问者独自一人,我只使用简单的group by
来完成这项工作对我来说也更有意义。这本来是我的建议:
GROUP BY s.visitor_id
HAVING COUNT(*) >= 2 AND SUM(revenue) = 0
但由于您想保留会话 ID,毕竟您确实需要分析函数:
SELECT visitor_id, session_id,
ROW_NUMBER() OVER (PARTITION BY visitor_id ORDER BY session_ts) as row_num
FROM
(
SELECT s.visitor_id, s.session_id, s.sessions_ts,
SUM(revenue) OVER (PARTITION BY s.visitor_id) as total,
COUNT(*) OVER (PARTITION BY s.visitor_id) as num_sessions
FROM sessions s INNER JOIN transactions t
ON s.session_id = t.session_id
WHERE s.session_ts >= '2020-01-01' AND s.session_ts < '2020-02-01'
) sub
WHERE total = 0 AND total_sessions >= 2
包含零美元列作为输出没有明确的目的,这就是我将它们排除在外的原因。您甚至可能不需要该行号列,但请注意它现在在外部查询中。
如果可能出现负收入,那么总和并不总是有效。考虑比较这两个值是否相等:
COUNT(*) OVER (PARTITION BY s.visitor_id)
和
COUNT(CASE WHEN revenue = 0 THEN 1 END) OVER (PARTITION BY s.visitor_id)
【讨论】:
以上是关于如何提取在 2020 年 1 月至少访问过两次但未进行交易的所有 visitor_id 的列表(在他们 1 月的任何一次访问中)的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Mock 应该至少被调用一次但被调用 0 次
在mysql中选择至少有两个[activity]且间隔时间至少为24小时的[sth]
意外行为 java 优先级队列。对象添加了一次但轮询了两次。怎么可能?