2013-10-07 126 views
2

这是一个非常简化的表格,但过程应该是相同的。我想计算登录之间的天数。这是表设置查询。计算行间表之间的日期差异[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; 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 

凡头是天-1的区别。 User_id(1)在2日和5日登录。所以他们的tau值是2,因为登录之间是两天。

User_id(2)由于在连续日期内登录,所以其值为0。

由于没有时间过去,第7次得到0。如果更容易,也可以标记为-1。

非常感谢您的帮助。非常感激。

编辑 澄清。 User_id(1),2013-10-05的tau值为1,因为它们在将当前日视为第7天时尚未重新登录。 例如,如果有人没有重新登录,他们的头值不断增加。因此,自从user_id = 1上次登录时,他们当前的tau值为1,并且该值每天不会再重新登录,因此每天都会增加1个。 再次感谢 - 特别是a_horse_with_no_name和Linger for the快速反应,并帮助我澄清一下这个问题

+0

我不明白你的编辑。您首先说的是您需要登录日期和上次登录日期之间的天数。我的答案告诉你如何得到这个。现在您需要登录日期和当前日期之间的天数。但是,您的结果表格仍然反映了您的第一个要求。那么你想要什么,登录日期和登录日期和当前日期之间的天数?你能解决你的结果表吗? – Linger

+0

@灵儿。你的回答是正确的,并显示我想要的。我想测量登录之间的天数。所以如果有人没有重新登录,他们的头值就会不断增加。因此,由于user_id = 1在5日上次登录,因此它们的tau值为1,并且该值每天都会不断增加1,因此它们不会重新登录。 –

+0

好的,如果我的答案是您正在查找的内容为了和最好的答案,你能将它标记为接受的答案吗? – Linger

回答

1

如果你没有在搜索结果介意空,那么你可以使用(SAMPLE):如果你想检查null并分配0然后使用

SELECT m.user_id, m.login_day, m.login_day - 
(
    SELECT MAX(login_day) 
    FROM tester AS s 
    WHERE m.user_id = s.user_id 
    AND s.login_day < m.login_day 
) - 1 AS DaysInBetween 
FROM tester AS m 

以下(SAMPLE):

SELECT TopL.user_id, TopL.login_day, 
     COALESCE(TopL.DaysInBetween, 0) As TotalD 
FROM (
     SELECT m.user_id, m.login_day, 
      m.login_day - 
      (
      SELECT MAX(login_day) 
      FROM tester AS s 
      WHERE m.user_id = s.user_id 
      AND s.login_day < m.login_day 
      ) - 1 AS DaysInBetween 
     FROM tester AS m 
     ) AS TopL 
ORDER BY user_id, 
     login_day 

这里是另一个查询来考虑(SAMPLE):

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 
3

这使你接近正确答案:

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) 

由于我不明白规则,为什么为user_id = 1“最后”登录生成2,但对于user_id 2最后登录生成0我不太确定如何修复第二个日志的错误显示in user_id = 1

+0

对不起,我忘记说我是在当天的第七天。因此,用户还没有登录2天或者1天。 –

+0

Tau基本上是从上次登录'之后'。谢谢 –

+0

@AndrewEscobedo:那么我不明白为什么user_id = 1的第一次登录获得2,但user_id = 2的第一次登录获得0.因为两者都是“第一次”登录,所以没有这样的事情“自上次以来”的dasys数量 –