Select SQLite 中按连续日期排列的行

Select Rows by Consecutive Dates in SQLite

我有一个 table 数据如下:

日志Table:

User Id Login Date
1 2022-01-03
1 2022-01-04
1 2022-01-10
1 2022-01-11
1 2022-01-12
1 2022-01-23
1 2022-01-25
1 2022-01-26
1 2022-01-27
1 2022-01-28

我想要做的是创建一个查询,其中 return 连续日期的最新登录行,使用 var_date 作为参数。

如果var_date是2022-01-29,那么结果是:

User Id Login Date
1 2022-01-25
1 2022-01-26
1 2022-01-27
1 2022-01-28

如果 var_date 是 2022-01-30,则不会 returned,因为 2022-01-29 不在 table.

如果 var_date 是 2022-01-24,则查询将 return 以 2022-01-23 作为登录日期的行。

我如何在 SQLite 中执行此操作?

谢谢。

这个问题是间隙和孤岛的变体,孤岛是每个用户的记录集群,具有连续的日期。这是一种使用解析函数的方法:

WITH cte AS (
    SELECT *, CASE WHEN julianday(LoginDate) -
              julianday(LAG(LoginDate) OVER (PARTITION BY UserID
                                             ORDER BY LoginDate))
                  > 1 THEN 1 ELSE 0 END AS counter
    FROM yourTable
),
cte2 AS (
    SELECT *, SUM(counter) OVER (PARTITION BY UserID ORDER BY LoginDate) AS grp
    FROM cte
)

SELECT UserID, LoginDate
FROM cte2 t1
WHERE LoginDate < '2022-01-29' AND
      grp = (SELECT t2.grp FROM cte2 t2
             WHERE t2.UserID = t1.UserID AND t2.LoginDate = '2022-01-28');

Demo

这两个 CTE 为每个用户的每个集群生成一个伪数据组。最终查询 returns 所有小于目标日期的记录,其组值与前一个日期相同。因此,对于给定用户没有即时记录的日期,查询将为 return 空集。

使用递归 CTE:

WITH cte(UserId, LoginDate) AS (
  SELECT :var_user_id, :var_date
  UNION ALL
  SELECT UserId, date(c.LoginDate, '-1 day')
  FROM cte c
  WHERE EXISTS (SELECT 1 FROM tablename t WHERE t.UserId = c.UserId AND t.LoginDate = date(c.LoginDate, '-1 day'))
)
SELECT * 
FROM cte 
WHERE LoginDate < (SELECT MAX(LoginDate) FROM cte); 

:var_user_id:var_date 更改为您想要的用户 ID 和日期值。

参见demo