确定谁丢失了活动

时间:2014-07-01 14:51:17

标签: sql sql-server

我的情况是事件按顺序发生,应该有逻辑上的进展。但是由于系统故障,一些事件丢失了,我需要能够识别它们。

我有2张桌子。

  1. NameTbl包含:

    eID  FirstNM  LastNM
    ---  -------  ------
    
  2. EventTbl包含:

    eID  EventLocation  EventNM  EventDate
    ---  -------------  -------  ---------
    
  3. 事物的逻辑顺序应该是:

    1. 唤醒(Wake
    2. 穿上衣服(GetDress
    3. 开车上班(DriveTo
    4. 开始工作(WorkBegin
    5. 无论出于何种原因,有些人错过了DriveTo事件,即使我知道它发生了。我想要做的是识别:弗吉尼亚州的所有人(FirstNMLastNM),其最后一个事件是WorkBegin,但前面没有DriveTo

      NameTbl:

      eID   FirstNM     LastNM
      ---   -------     ------
       1     John        Doe
       2     Mary        West
       3     Derek       Smith
      

      EventTbl:

      eID    EventLocation   EventNM            EventDate
      ---    -------------   ---------     -------------------
       1       Virginia       Wake         2014-06-30 06:00:00
       1       Virginia       GetDress     2014-06-30 06:30:00
       1       Virginia       DriveTo      2014-06-30 06:45:00
       1       Virginia       Work         2014-06-30 07:00:00
       2       Virginia       Wake         2014-06-30 05:00:00
       2       Virginia       GetDress     2014-06-30 06:00:00
                  (Missing Event!)
       2       Virginia       Work         2014-06-30 07:00:00
       3       Virginia       Wake         2014-06-29 03:00:00
       3       Virginia       GetDress     2014-06-29 04:00:00
                  (Missing Event!)
       3       Virginia       Work         2014-06-29 04:30:00
      

      期望的结果:

      FirstNM   LastNM     EventLocation        WorkDate
      -------   ------     -------------    -------------------
       Mary      West        Virginia       2014-06-30 07:00:00
       Derek     Smith       Virginia       2014-06-29 04:30:00
      

2 个答案:

答案 0 :(得分:0)

DECLARE @NameTBL TABLE
(   
    eID INT,
    FirstNM VARCHAR(50),
    LastNM VARCHAR(50)
)

INSERT INTO @NameTBL
( eID, FirstNM, LastNM )
VALUES
(1     ,'John'        ,'Doe'),
(2     ,'Mary'        ,'West'),
(3     ,'Derek'       ,'Smith');


DECLARE @EventTBL TABLE
(
    eID INT,
    EventLocation VARCHAR(50),
    EventNM VARCHAR(50),
    EventDate DATETIME
)

DECLARE @EventType TABLE
( 
    EventName VARCHAR(50)
)

INSERT INTO @EventType
( EventName )
VALUES
( 'Wake' ),
('GetDress'),
('DriveTo'),
('Work')

INSERT INTO @EventTBL
( eID, EventLocation, EventNM, EventDate )
VALUES
(1       ,'Virginia'       ,'Wake'         ,'2014-06-30 06:00:00'),
(1       ,'Virginia'       ,'GetDress'     ,'2014-06-30 06:30:00'),
(1       ,'Virginia'       ,'DriveTo'      ,'2014-06-30 06:45:00'),
(1       ,'Virginia'       ,'Work'         ,'2014-06-30 07:00:00'),
(2       ,'Virginia'       ,'Wake'         ,'2014-06-30 05:00:00'),
(2       ,'Virginia'       ,'GetDress'     ,'2014-06-30 06:00:00'),
(2       ,'Virginia'       ,'Work'         ,'2014-06-30 07:00:00'),
(3       ,'Virginia'       ,'Wake'         ,'2014-06-29 03:00:00'),
(3       ,'Virginia'       ,'GetDress'     ,'2014-06-29 04:00:00'),
(3       ,'Virginia'       ,'Work'         ,'2014-06-29 04:30:00');

SELECT m.* FROM
(
    SELECT n.eID, n.FirstNM, n.LastNM, e.EventName, t.EventDate, t.EventLocation
    FROM @NameTBL n
    OUTER APPLY
    (
        SELECT DISTINCT DATEADD(dd, 0, DATEDIFF(dd, 0, t.EventDate)) EventDate, 
                    t.EventLocation
        FROM @EventTBL t
        WHERE t.eID = n.eID
    ) t
    CROSS JOIN @EventType e
) m
LEFT JOIN @EventTBL d
    ON d.eID = m.eID
    AND d.EventNM = m.EventName
    AND DATEADD(dd, 0, DATEDIFF(dd, 0, d.EventDate)) = m.EventDate
WHERE d.eID IS NULL

我添加了一个eventtype表来查找所有唯一的事件(可能只是查询了主表,但如果所有记录都缺少一个事件,那么你永远不会知道) 这输出:

2   Mary    West    DriveTo 2014-06-30 00:00:00.000 Virginia
3   Derek   Smith   DriveTo 2014-06-29 00:00:00.000 Virginia

答案 1 :(得分:0)

另一种方法。 SQL小提琴:

WITH cteEvents
AS
(
  SELECT 'Wake' AS Event
  UNION ALL
  SELECT 'GetDress' AS Event
  UNION ALL
  SELECT 'DriveTo' AS Event
  UNION ALL
  SELECT 'Work' AS Event
),
cteEventMatrix
AS
(
  SELECT    et.eID,
            et.EventLocation,
            e.Event,
            MAX(et.EventDate) AS EventDate
  FROM      EventTbl et, cteEvents e
  GROUP BY  et.eID,
            et.EventLocation,
            e.Event
)

SELECT    n.FirstNM,
          n.LastNM,
          em.EventLocation,
          em.EventDate
FROM      cteEventMatrix em INNER JOIN NameTbl n
          ON  em.eID = n.eID
WHERE     NOT EXISTS (SELECT 1 FROM EventTbl WHERE eID = em.eID AND EventNM = em.Event)

您想要创建所有可能的eID和事件的矩阵。然后,您要查询EventTbl以查看哪些不存在。我们可以使用MAX的EventDate,因为它是您正在寻找的Drive,所以Work是当天的最新项目,并且它存在。