在同一查询列中选择具有与其他事件相关的事件的行

时间:2019-04-19 07:19:28

标签: sql sql-server tsql union

我需要选择EventTypeID = 19的行,而该行没有相关的EventtypeID = 21,正好是4分钟前针对同一EmployeeID的LoggedOn。这是查询行和一些原始输出:

SELECT * FROM
    (
        SELECT rcp..EventLogEntries.EmployeeID, rcp..EventLogEntries.EventTypeID, rcp..EventLogEntries.TerminalID, rcp..EventLogEntries.LoggedOn
        FROM rcp..EventLogEntries
        WHERE rcp..EventLogEntries.terminalid = 3
        UNION
        SELECT viso..AccessUserPersons.UserExternalIdentifier, rcp..EventTypes.ID, rcp..Terminals.ID, viso..EventLogEntries.LoggedOn
        FROM viso..EventLogEntries, viso..AccessUserPersons, rcp..Terminals, rcp..EventTypes
        WHERE viso..EventLogEntries.LocationID = 10
        AND viso..EventLogEntries.EventCode = 615
        AND rcp..EventTypes.Code = 36
        AND viso..EventLogEntries.PersonID = viso..AccessUserPersons.ID
        AND viso..EventLogEntries.locationID = rcp..Terminals.TerminalTAID
    ) results
ORDER BY LoggedOn


EmployeeID  EventTypeID TerminalID  LoggedOn
273         19          3           2018-12-04 12:31:23.000
273         21          3           2018-12-04 12:34:18.000
483         19          3           2018-12-04 12:40:10.000
268         19          3           2018-12-04 13:19:23.000
273         21          3           2018-12-04 13:28:00.000
273         19          3           2018-12-04 13:32:00.000
459         19          3           2018-12-04 15:01:04.000

我需要实现的是:

EmployeeID  EventTypeID TerminalID  LoggedOn
273         19          3           2018-12-04 12:31:23.000
483         19          3           2018-12-04 12:30:10.000
268         19          3           2018-12-04 13:19:23.000
459         19          3           2018-12-04 15:01:04.000

在那种情况下,TerminalID列的值始终为3,并且与任何查询条件都没有关系,但是在进一步处理中,对于语法要求,它必须在输出中。

2 个答案:

答案 0 :(得分:0)

使用WHERE中的条件联接表的错误做法。 WHERE块首先需要用于过滤。 别名有助于缩短代码。

SELECT * FROM
    (
        SELECT EmployeeID, EventTypeID, TerminalID, LoggedOn
        FROM rcp..EventLogEntries
        WHERE terminalid = 3
        UNION
        SELECT p.UserExternalIdentifier, et.ID, t.ID, el.LoggedOn
        FROM viso..EventLogEntries el
        JOIN viso..AccessUserPersons p ON el.PersonID = p.ID
        JOIN rcp..Terminals t ON el.locationID = t.TerminalTAID
        JOIN rcp..EventTypes et ON --!!! no any condition here
        WHERE el.LocationID = 10
          AND el.EventCode = 615
          AND et.Code = 36
    ) results
ORDER BY LoggedOn

尝试使用以下内容:

WITH cteData AS
    (
        SELECT EmployeeID, EventTypeID, TerminalID, LoggedOn
        FROM rcp..EventLogEntries
        WHERE terminalid = 3
        UNION
        SELECT p.UserExternalIdentifier, et.ID, t.ID, el.LoggedOn
        FROM viso..EventLogEntries el
        JOIN viso..AccessUserPersons p ON el.PersonID = p.ID
        JOIN rcp..Terminals t ON el.locationID = t.TerminalTAID
        JOIN rcp..EventTypes et ON --!!! no any condition here
        WHERE el.LocationID = 10
          AND el.EventCode = 615
          AND et.Code = 36
    )
SELECT q19.*
FROM
  (
    SELECT *
    FROM cteData
    WHERE EventTypeID=19
  ) q19
LEFT JOIN
  (
    SELECT *
    FROM cteData
    WHERE EventTypeID=21
  ) q21
ON q19.EmployeeID=q21.EmployeeID
WHERE (DATEDIFF(MINUTE,q19.LoggedOn,q21.LoggedOn)>4 OR q21.LoggedOn IS NULL)

如果不需要任何条件,可以使用CROSS JOIN

我使用您的数据得到了您的结果:

WITH cteData AS(
  SELECT *
  FROM (VALUES
        (273,19,3,CAST('2018-12-04 12:31:23.000' AS datetime)),
        (273,21,3,CAST('2018-12-04 12:34:18.000' AS datetime)),
        (483,19,3,CAST('2018-12-04 12:40:10.000' AS datetime)),
        (268,19,3,CAST('2018-12-04 13:19:23.000' AS datetime)),
        (273,21,3,CAST('2018-12-04 13:28:00.000' AS datetime)),
        (273,19,3,CAST('2018-12-04 13:32:00.000' AS datetime)),
        (459,19,3,CAST('2018-12-04 15:01:04.000' AS datetime))
    )v(EmployeeID,EventTypeID,TerminalID,LoggedOn)
)
SELECT q19.*
FROM
  (
    SELECT *
    FROM cteData
    WHERE EventTypeID=19
  ) q19
LEFT JOIN
  (
    SELECT *
    FROM cteData
    WHERE EventTypeID=21
  ) q21
ON q19.EmployeeID=q21.EmployeeID
WHERE (DATEDIFF(MINUTE,q19.LoggedOn,q21.LoggedOn)>4 OR q21.LoggedOn IS NULL)

答案 1 :(得分:0)

这部分所做的小改动:

ON q19.EmployeeID=q21.EmployeeID AND q19.LoggedOn=dateadd(mi, 4, q21.LoggedOn)
WHERE q21.LoggedOn IS NULL