【问题标题】:Creating SQL query to return oldest date for event and duration until different event创建 SQL 查询以返回事件的最旧日期和持续时间,直到不同的事件
【发布时间】:2013-12-05 13:08:13
【问题描述】:

我正在尝试编写一个 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;

【问题讨论】:

    标签: sql date ms-access ado duration


    【解决方案1】:

    您的测试数据与您的预期结果不符。 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 对象,以便能够创建和使用多个查询。

    【讨论】:

      猜你喜欢
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多