连续几天在sql中

eug*_*ene 7 sql postgresql

我发现连续几天有很多stackoverflow QnAs.
仍然答案太短,我无法理解发生了什么.

具体来说,我会组成一个模型(或表)
(如果它有所不同,我正在使用postgresql.)

CREATE TABLE work (
    id integer NOT NULL,
    user_id integer NOT NULL,
    arrived_at timestamp with time zone NOT NULL
);


insert into work(user_id, arrived_at) values(1, '01/03/2011');
insert into work(user_id, arrived_at) values(1, '01/04/2011');
Run Code Online (Sandbox Code Playgroud)
  1. (最简单的形式)对于给定的用户,我想找到最后连续的日期范围.

  2. (我的最终目标)对于给定的用户,我想找到他连续的工作日.
    如果他昨天来上班,他仍然(截至今天)有连续工作的机会.所以我昨天连续几天告诉他.
    但如果他昨天错过了,他的连续几天是0或1,取决于他今天是否来.

今天说是第8天.

3 * 5 6 7 * = 3 days (5 to 7)
3 * 5 6 7 8 = 4 days (5 to 8)
3 4 5 * 7 * = 1 day (7 to 7)
3 * * * * * = 0 day 
3 * * * * 8 = 1 day (8 to 8)
Run Code Online (Sandbox Code Playgroud)

Dip*_*aul 3

这是我使用这个问题的解决方案CTE

WITH RECURSIVE CTE(attendanceDate)
AS
(
   SELECT * FROM 
   (
      SELECT attendanceDate FROM attendance WHERE attendanceDate = current_date 
      OR attendanceDate = current_date - INTERVAL '1 day' 
      ORDER BY attendanceDate DESC
      LIMIT 1
   ) tab
   UNION ALL

   SELECT a.attendanceDate  FROM attendance a
   INNER JOIN CTE c
   ON a.attendanceDate = c.attendanceDate - INTERVAL '1 day'
) 
SELECT COUNT(*) FROM CTE;
Run Code Online (Sandbox Code Playgroud)

检查SQL Fiddle中的代码

以下是查询的工作原理:

  1. 它从表中选择今天的记录attendance。如果今天的记录不可用,则选择昨天的记录
  2. 然后它不断递归地添加最少日期之前一天的记录

如果您想选择最新的连续日期范围,而不管用户最近一次出勤是什么时候(今天、昨天或 x 天前),则 CTE 的初始化部分必须替换为以下代码片段:

SELECT MAX(attendanceDate) FROM attendance
Run Code Online (Sandbox Code Playgroud)

[编辑] 这是 SQL Fiddle 的查询,它解决了您的问题#1:SQL Fiddle