在MySQL中计算连续示例

pdkcd3nj  于 2023-01-08  发布在  Mysql
关注(0)|答案(2)|浏览(130)

我有一个关于MySQL窗口的问题

SELECT 
Client,
User,
Date,
Flag,
lag(Date) over (partition by Client,User order by Date asc) as last_date,
lag(Flag) over (partition by Client,User order by Date  asc) as last_flag,
case when Flag = 1 and last_flag = 1 then 1 else 0 end as consecutive
FROM db.tbl

这个查询返回如下所示的内容:我试图计算出每个用户最近的Flag列连续为1的次数,如果他们有11110000111,那么我们应该取最后三次出现的1来确定他们有连续3次的标志。
我需要提取连续标志的开始和结束日期。
我该怎么做呢,有没有人能帮我:)

如果我们使用11110000111的示例,则应仅提取111,因此该客户的3个最近日期。因此,在下面的示例中,我们需要将10.01.2023作为第一个日期,将24.01.2023作为最后一个日期。连续计数应为3

输出:

b0zn9rqh

b0zn9rqh1#

使用聚合函数和字符串函数:

WITH cte AS (
  SELECT Client, User,
         GROUP_CONCAT(CASE WHEN Flag THEN Date END ORDER BY Date) AS dates,
         CHAR_LENGTH(SUBSTRING_INDEX(GROUP_CONCAT(Flag ORDER BY Date SEPARATOR ''), '0', '-1')) AS consecutive
  FROM tablename
  GROUP BY Client, User
)
SELECT Client, User,
       NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(dates, ',', -consecutive), ',', 1), '') AS first_date,
       CASE WHEN consecutive > 0 THEN SUBSTRING_INDEX(dates, ',', -1) END AS last_date,
       consecutive 
FROM cte;

另一个具有窗口函数和条件聚集的解决方案:

WITH 
  cte1 AS (SELECT *, SUM(NOT Flag) OVER (PARTITION BY Client, User ORDER BY Date) AS grp FROM tablename),
  cte2 AS (SELECT *, MAX(grp) OVER (PARTITION BY Client, User) AS max_grp FROM cte1)
SELECT Client, User,
       MIN(CASE WHEN Flag THEN Date END) AS first_date,
       MAX(CASE WHEN Flag THEN Date END) AS last_date,
       SUM(Flag) AS consecutive
FROM cte2 
WHERE grp = max_grp
GROUP BY Client, User;

请参见demo

oknwwptz

oknwwptz2#

尝试使用更简单的查询来获得结果,下面是我利用lastDate和lastFlag列的方法。
运行here

WITH eTT 
AS 
( SELECT Client, User, NULLIF(MAX(Date), 
  (SELECT MAX(Date) FROM tt t2 WHERE t1.Client=t2.Client AND t1.User=t2.User)) as endDate 
  FROM tt t1 WHERE LastFlag=0 OR LastFlag IS NULL GROUP BY Client, User
)
SELECT Client, User, 
(CASE WHEN MAX(endDate) IS NULL THEN NULL ELSE MIN(Date) END) as first_date, 
(CASE WHEN MAX(endDate) IS NULL THEN NULL ELSE MAX(Date) END) as last_date, 
(CASE WHEN MAX(endDate) IS NULL THEN NULL ELSE COUNT(endDate) END) as consecutive 
FROM tt LEFT JOIN eTT USING (Client, User) 
WHERE Date >= endDate OR endDate IS null GROUP BY Client, User;
    • 编辑**

原始表没有LastDateLastFlag列,是使用OP的初始查询创建的。
由于所使用的方法没有得到明显的支持,但我得到的印象是,OP不知何故设法做到这一点,在他们的一方。
因此,可以在包含该查询的eTT之前添加另一个称为tt的cte。

相关问题