SQL查询以统计出现次数,但在特定值处停止
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL查询以统计出现次数,但在特定值处停止相关的知识,希望对你有一定的参考价值。
我需要查询一堆购买行,其中的结构有点棘手。因此,基本上,这是一项订阅服务,(每个用户的)行如下所示:
[当用户进行(新)购买时,它作为PURCHASE
进入数据库。发生定期付款时,将其标记为RENEW
。如果用户取消订阅然后重新输入,则将其标记为新的Purchase
。
我想对我的查询回答:如果购买了2019-07-01
,那么到今天为止有多少次续订?如果在“ 2019-07-01”之后还有其他购买,则应该停止计数(因为这意味着已经购买了另一个订阅)。
我希望看到从RENEWALS
开始的购买中获得了多少2019-07-01
的分组。
结果看起来像这样:
这对于SQL查询来说是否太复杂了,或者有可能吗?
该解决方案对几乎所有DBMS都是安全的:
SELECT sq2.renewals,
COUNT(sq2.renewals) renewalscount
FROM ( SELECT sq1.userid,
sq1.prevdate,
COUNT(CASE WHEN t3.type = 'RENEW'
THEN 1 END) renewals
FROM test t3
LEFT JOIN ( SELECT t1.userid,
t1.pdate prevdate,
COALESCE(MIN(t2.pdate), '2099-01-01') nextdate
FROM test t1
LEFT JOIN test t2 ON t1.userid = t2.userid
AND t1.pdate < t2.pdate
AND t2.type = 'PURCHASE'
WHERE t1.type = 'PURCHASE'
GROUP BY t1.userid, t1.pdate ) sq1 ON t3.userid = sq1.userid
AND t3.pdate BETWEEN sq1.prevdate
AND sq1.nextdate
GROUP BY sq1.userid,
sq1.prevdate ) sq2
GROUP BY sq2.renewals
ORDER BY sq2.renewals;
[fiddle(包括单独的子查询代码和最少的注释)。
我不确定您要为水桶设定什么规则,所以这将是部分答案。 (例如,如果用户已连续3个月和5个月被订阅,那么在两个不同的时间,他是否同时属于两个存储桶?)
我进行了查询,以按照您需要的更实用的格式重新组合数据,您应该能够自己创建存储桶:)
SET @grp = 0;
SELECT MIN(t.userId) AS userId, MIN(t.orderDate) AS sub_start, MAX(t.orderDate) AS sub_end, COUNT(t.orderId)
FROM (
SELECT o.*, CASE WHEN o.type='PURCHASE' THEN @grp:=@grp+1 ELSE @grp END AS grp
FROM orders o
ORDER BY o.userId, o.orderDate ASC
) AS t
GROUP BY t.grp
我只是按顺序和日期在表上进行迭代,以分配一个grp
(例如,每行的一组连续订阅,然后我们可以按grp
进行跳转。
[请注意,我假设您有一个userId
行(或等效表),并且每个订阅组始终以type='PURCHASED'
开头,如果由于某些原因缺少'PURCHASED'
行中的一个,它将使这些组弄乱了]] >
我希望这会有所帮助:)
以上是关于SQL查询以统计出现次数,但在特定值处停止的主要内容,如果未能解决你的问题,请参考以下文章