这是一个非常简化的表,但过程应该是相同的。我想计算登录之间的天数。这是表设置查询。
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的快速回复并帮助我澄清问题
答案 0 :(得分: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,“last”登录生成2但是对于user_id 2,最后一次登录生成0我不太确定如何修复第二次登录的错误显示user_id = 1
答案 1 :(得分:1)
如果您不介意在结果中使用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