2

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

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 天的差异。User_id(1) 于 2 日和 5 日登录。所以他们的 tau 值是 2,因为登录间隔是两天。

User_id(2) 的值为 0,因为他们连续几天登录。

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

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

编辑 澄清。User_id(1), 2013-10-05 的 tau 值为 1,因为他们在将当天视为 7 日时尚未重新登录。例如,如果有人没有重新登录,他们的 tau 值会不断增加。因此,自从 user_id=1 上次登录是在 5 日以来,他们目前的 tau 值为 1,并且该值将在他们不重新登录的每一天持续增加 1。再次感谢 a_horse_with_no_name 和 Linger 的快速回答并帮助我澄清问题

4

2 回答 2

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;

输出:

用户 ID | 登录日 | 头   
--------+------------+--------
1 | 2013-10-02 | 2     
1 | 2013-10-05 | (无效的)
2 | 2013-10-03 | 0     
2 | 2013-10-04 | 2     
2 | 2013-10-07 | (无效的)

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

于 2013-10-07T18:36:40.280 回答
2

如果您不介意结果中的 Null,则可以使用(SAMPLE):

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

如果要检查 Null 并分配 0,请使用以下 ( 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
于 2013-10-07T18:33:24.407 回答