我有一个表:例如,session是表的名称 使用列:Id,sessionDate,user_id
我需要什么: Delta应该是一个新的计算列
Id | sessionDate | user_id | Delta in days
------------------------------------------------------
1 | 2011-02-20 00:00:00 | 2 | NULL
2 | 2011-03-21 00:00:00 | 2 | NULL
3 | 2011-04-22 00:00:00 | 2 | NULL
4 | 2011-02-20 00:00:00 | 4 | NULL
5 | 2011-03-21 00:00:00 | 4 | NULL
6 | 2011-04-22 00:00:00 | 4 | NULL
Delta是时间戳之间的差异 我想要的是上一行的Delta Timestamp(以天为单位)和user_id分组的当前行的结果。
这应该是结果:
Id | sessionDate | user_id | Delta in Days
------------------------------------------------------
1 | 2011-02-20 00:00:00 | 2 | NULL
2 | 2011-02-21 00:00:00 | 2 | 1
3 | 2011-02-22 00:00:00 | 2 | 1
4 | 2011-02-20 00:00:00 | 4 | NULL
5 | 2011-02-23 00:00:00 | 4 | 3
6 | 2011-02-25 00:00:00 | 4 | 2
我已经有针对特定user_id的解决方案:
SELECT user_id, sessionDate,
abs(DATEDIFF((SELECT MAX(sessionDate) FROM session WHERE sessionDate < t.sessionDate and user_id = 1), sessionDate)) as Delta_in_days
FROM session AS t
WHERE t.user_id = 1 order by sessionDate asc
但是对于更多user_ids我找不到任何解决方案
希望有人可以帮助我。答案 0 :(得分:2)
试试这个:
drop table a;
create table a( id integer not null primary key, d datetime, user_id integer );
insert into a values (1,now() + interval 0 day, 1 );
insert into a values (2,now() + interval 1 day, 1 );
insert into a values (3,now() + interval 2 day, 1 );
insert into a values (4,now() + interval 0 day, 2 );
insert into a values (5,now() + interval 1 day, 2 );
insert into a values (6,now() + interval 2 day, 2 );
select t1.user_id, t1.d, t2.d, datediff(t2.d,t1.d)
from a t1, a t2
where t1.user_id=t2.user_id
and t2.d = (select min(d) from a t3 where t1.user_id=t3.user_id and t3.d > t1.d)
这意味着:在user_ids和相邻的datetime条目上将表连接到自身并计算差异。
答案 1 :(得分:1)
如果id
确实是连续的(如您的示例数据中所示),则以下内容应非常有效:
select t.id, t.sessionDate, t.user_id, datediff(t2.sessiondate, t.sessiondate)
from table t left outer join
table tprev
on t.user_id = tprev.user_id and
t.id = tprev.id + 1;
还有另一种使用变量的有效方法。这样的事情应该有效:
select t.id, t.sessionDate, t.user_id, datediff(prevsessiondate, sessiondate)
from (select t.*,
if(@user_id = user_id, @prev, NULL) as prevsessiondate,
@prev := sessiondate,
@user_id := user_id
from table t cross join
(select @user_id := 0, @prev := 0) vars
order by user_id, id
) t;
(这些查询存在一个小问题,select
子句中的变量可能无法按照我们期望的顺序进行评估。这可以修复,但它会使查询复杂化,这通常会的工作。)
答案 2 :(得分:0)
虽然你已经选择了答案,但另一种方法是实现它
SELECT
t1.Id,
t1.sessionDate,
t1.user_id,
TIMESTAMPDIFF(DAY,t2.sessionDate,t1.sessionDate) as delta
from myTable t1
left join myTable t2
on t1.user_id = t2.user_id
AND t2.Id = (
select max(Id) from myTable t3
where t1.Id > t3.Id AND t1.user_id = t3.user_id
);
<强> DEMO 强>