创建SQL查询以返回事件和持续时间的最早日期,直到不同的事件

时间:2013-11-21 07:10:01

标签: sql date ms-access ado duration

我正在尝试编写SQL查询(使用ADO从Excel查询Access)以返回每个不同的UserID以及EventID = 916和最早最旧日期> 916事件后该用户发生的EventID = 944的日期。另外,我想计算日期之间的持续时间。

测试数据如下:

create table table_name
(
  EventID int,
  UserId int,
  MsgVar1 varchar(4),
  MsgVar2 varchar(4),
  EventDate date
);

insert into table_name (EventId,UserId,MsgVar1,MsgVar2,EventDate) values 
(916,123456,'x', 'x','20110920'),
(944,123456,'x','x','20110923'),
(945,123456,'x','x','20110925'),
(916,123456,'x', 'x','20110928'),
(944,123456,'x', 'x','20110928'),
(916,123458,'x', 'x','20110919'),
(944,123458,'x','x','20110928');

查询应返回以下内容:

UserId | Event916Date | Event944Date | Duration
-----------------------------------------------
123456 | 20110920     | 20110923     | 3
123458 | 20110919     | 20110928     | 9

我的出发点如下,但是现在这会返回所有 944事件,而不仅仅是最旧的事件。

select start.UserID, start.EventDate start, end.EventDate end, datediff(end.EventDate, start.EventDate) duration
from (
    select *, (
        select UserID from table_name L2 where L2.EventDate>L1.EventDate and L2.UserId=L1.UserId order by EventDate limit 1
    ) stop_id from table_name L1
) start
join table_name end on end.UserID=start.stop_id
where start.EventID=916 and end.EventID=944;

1 个答案:

答案 0 :(得分:0)

您的测试数据与预期结果不符。 eventID 916的latest日期为20110928,用户ID 123456以及该日期之后该用户的earliest 944日期也是20110928,仅查看提供的样本数据。我删除了用户123456的最后一个事件ID 916,并且能够获得预期的结果。

我将测试数据更改为以下内容:

insert into table_name (EventId,UserId,MsgVar1,MsgVar2,EventDate) values
(944,123456,'x','x','20110910'),
(916,123456,'x','x','20110920'),
(944,123456,'x','x','20110923'),
(945,123456,'x','x','20110925'),
(944,123456,'x','x','20110928'),
(916,123458,'x','x','20110919'),
(944,123458,'x','x','20110928');

我使用单个查询得到的结果最接近,但它不起作用,因为您不能在后续子查询中使用来自一个子查询的别名结果。也许其他人会给你一个查询答案,因为它似乎应该是可行的。

select t1.userID, 
(select max(eventdate) from table_name t2 where t1.userid = t2.userid and eventid = 916) as Event916Date
from table_Name t1, 
(select t3.userID, 
(select min(eventdate) from table_name t4 where t4.userid = t3.userid and eventid = 944 and eventDate >= t1.Event916Date) as Event944Date
from table_Name t3) as t2
group by t1.userID

在访问中,我可以使用一些查询来完成此操作。

T1:获取活动916和每个用户的最长活动日期

SELECT table_name.UserId, Max(table_name.EventDate) AS MaxOfEventDate
FROM table_name
GROUP BY table_name.UserId, table_name.EventID
HAVING (((table_name.EventID)=916));

T2:获取944的事件日期以及每个用户的日期

SELECT t1.UserId, table_name.EventDate
FROM table_name INNER JOIN t1 ON table_name.UserId = t1.UserId
WHERE (((table_name.EventDate)>[maxofeventdate]) AND ((table_name.eventId)=944));

T3:为每个用户获取最小事件日期944

SELECT t2.UserId, Min(t2.EventDate) AS MinOfEventDate
FROM t2
GROUP BY t2.UserId;

T4:最终查询显示两者并计算持续时间

SELECT t1.UserId, t1.MaxOfEventDate, t3.MinOfEventDate, [MinOfEventDate]-[MaxOfEventDate] AS Duration
FROM t1 INNER JOIN t3 ON t1.UserId = t3.UserId;

如果从excel使用ADO,则应该可以访问querydef对象,以便能够创建和使用多个查询。