计算表内行与行之间的日期差[Postgresql]

计算表内行与行之间的日期差[Postgresql],sql,postgresql,Sql,Postgresql,这是一个非常简化的表,但过程应该是相同的。我想计算两次登录之间的天数。这是表设置查询 create table tester (user_id int, login_day date); insert into tester (user_id,login_day) values (1,'2013-10-02'), (1,'2013-10-05'), (2,'2013-10-03'), (2,'2013-10-04'), (2,'2013-10-07'); 为此: user_id

这是一个非常简化的表,但过程应该是相同的。我想计算两次登录之间的天数。这是表设置查询

create table tester (user_id int, login_day date);

insert into tester (user_id,login_day) 
values 
 (1,'2013-10-02'),
 (1,'2013-10-05'),
 (2,'2013-10-03'),
 (2,'2013-10-04'),
 (2,'2013-10-07');
为此:

user_id; login_day
     1;  "2013-10-02"
     1;  "2013-10-05"
     2;  "2013-10-03"
     2;  "2013-10-04"
     2;  "2013-10-07"
结果表应如下所示:

user_id; login_day; tau
     1;"2013-10-02"; 2
     1;"2013-10-05"; 1 --see edit
     2;"2013-10-03"; 0
     2;"2013-10-04"; 2 
     2;"2013-10-07"; 0
其中tau是第1天的差值。 用户id(1)在2号和5号登录。所以他们的tau值是2,因为两次登录间隔两天

用户_id(2)的值为0,因为他们连续几天登录

第七个得到0,因为没有时间过去。如果更简单的话,也可以标记为-1

非常感谢你的帮助。非常感谢

编辑 澄清用户_id(1),2013-10-05的tau值为1,因为他们在将当天视为第7天时尚未重新登录。 e、 因此,如果有人没有重新登录,他们的tau值会不断增加。因此,由于用户_id=1上次登录是在5日,因此他们当前的tau值为1,并且该值将在他们不重新登录的每天持续增加1。
再次感谢一位没有名字的马,Linger的快速回答,并帮助我澄清问题

如果你不介意结果为空,那么你可以使用()


这给了你几乎正确的答案:

select user_id, 
       login_day,
       lead(login_day) over (partition by user_id order by user_id) - login_day - 1 as tau
from tester
order by user_id, login_day;
输出:

user_id | login_day | tau --------+------------+------- 1 | 2013-10-02 | 2 1 | 2013-10-05 | (null) 2 | 2013-10-03 | 0 2 | 2013-10-04 | 2 2 | 2013-10-07 | (null) 用户id |登录日|头 --------+------------+------- 1 | 2013-10-02 | 2 1 | 2013-10-05 |(空) 2 | 2013-10-03 | 0 2 | 2013-10-04 | 2 2 | 2013-10-07 |(空)
由于我不理解规则,为什么用户_id=1的“最后一次”登录会生成2,而用户_id 2的最后一次登录会生成0我不太确定如何修复用户_id=1的第二次登录的错误显示。因此,用户已经有2天没有登录了,更确切地说是1天没有登录。Tau基本上是“自上次登录后的天”。Thanks@AndrewEscobedo:那么我不明白为什么用户_id=1的第一次登录得到2,而用户_id=2的第一次登录得到0。由于这两个都是“第一次”登录,因此没有“自上次”以来的dasys数之类的内容。很抱歉,再次没有澄清。用户_id=1在2日创建了该帐户。他们下一次登录是第五次=两天的差异。用户_id=2在第3天创建了帐户,并在第4天重新登录==连续登录天数结果为0。用户_id=1的tau为1(显示为2),因为当将当天视为第7天时,他们一整天都没有重新登录。如果他们在第8天登录,那么他们的tau将变为2。我不理解您的编辑。您首先说您想要的是登录日期和上一个登录日期之间的天数。我的答案告诉你如何做到这一点。现在您需要登录日期和当前日期之间的天数。但是,您的结果表仍然反映了您的第一个请求。那么,您想要什么,登录之间的天数还是登录日期和当前日期的差异?你能修好你的成绩表吗?@Linger。你的回答是正确的,说明了我想要什么。我想测量两次登录之间的天数。因此,如果有人没有重新登录,他们的tau值会不断增加。因此,由于用户_id=1上次登录是在5日,因此他们当前的tau值为1,并且该值将在他们不重新登录的情况下每天持续增加1。好的,如果我的答案是您正在寻找的答案,并且是最佳答案,您能将其标记为已接受的答案吗?谢谢这一点-非常适合我的需要。注意:在Postgres9.6中,我得到了一个错误
错误:运算符不存在:interval-integer
。将
-1作为DaysInBetween
更改为
-interval“1天”作为DaysInBetween
为我解决了这个问题。
SELECT TopL.user_id, TopL.login_day,
       CASE (COALESCE(TopL.DaysInBetween, 0)) WHEN '-1'
          THEN '0' ELSE COALESCE(TopL.DaysInBetween, 0) END
          As TotalD
FROM (
       SELECT m.user_id, m.login_day, 
         COALESCE(
         (
           SELECT MIN(login_day)
           FROM tester AS s 
           WHERE m.user_id = s.user_id 
           AND s.login_day > m.login_day
         )- m.login_day - 1, current_date - m.login_day-1)
         AS DaysInBetween
       FROM tester AS m
       ) AS TopL
ORDER BY user_id, 
         login_day
select user_id, 
       login_day,
       lead(login_day) over (partition by user_id order by user_id) - login_day - 1 as tau
from tester
order by user_id, login_day;
user_id | login_day | tau --------+------------+------- 1 | 2013-10-02 | 2 1 | 2013-10-05 | (null) 2 | 2013-10-03 | 0 2 | 2013-10-04 | 2 2 | 2013-10-07 | (null)