SQL查询以统计出现次数,但在特定值处停止

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL查询以统计出现次数,但在特定值处停止相关的知识,希望对你有一定的参考价值。

我需要查询一堆购买行,其中的结构有点棘手。因此,基本上,这是一项订阅服务,(每个用户的)行如下所示:

enter image description here

[当用户进行(新)购买时,它作为PURCHASE进入数据库。发生定期付款时,将其标记为RENEW。如果用户取消订阅然后重新输入,则将其标记为新的Purchase

我想对我的查询回答:如果购买了2019-07-01,那么到今天为止有多少次续订?如果在“ 2019-07-01”之后还有其他购买,则应该停止计数(因为这意味着已经购买了另一个订阅)。

我希望看到从RENEWALS开始的购买中获得了多少2019-07-01的分组。

结果看起来像这样:

enter image description here

这对于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个月被订阅,那么在两个不同的时间,他是否同时属于两个存储桶?)

我进行了查询,以按照您需要的更实用的格式重新组合数据,您应该能够自己创建存储桶:)

DB fiddle

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查询以统计出现次数,但在特定值处停止的主要内容,如果未能解决你的问题,请参考以下文章

mysql特定字符出现次数统计

vim怎么正则查询一个词出现的次数

Transact-SQL统计某字段中的值第一次出现后的2小时内出现的次数

连接 2 个表并计算 SQL 中特定字段的出现次数

Excel如何统计某单元格内特定字符串出现的次数

SQL中如何统计查询结果中某一列重复值的个数?