在单行结果中获取相应的行?

Get corresponding rows in single line result?

给定以下数据,我将如何获得下面想要的结果?

Timestamp | Session ID | Event   | Name
------------------------------------------
08:15     | 89         | Login   | Scott
08:16     | 89         | Edit    | Scott
08:16     | 92         | Login   | John
08:17     | 92         | Refresh | John
08:23     | 89         | Logout  | Scott
08:28     | 92         | Logout  | John
08:30     | 96         | Login   | Scott
08:37     | 96         | Logout  | Scott

期望的结果(本质上是会话持续时间列表):

Name  | Login | Logout
------------------------
Scott | 8:15  | 8:23
John  | 8:16  | 8:28
Scott | 8:30  | 8:37

编辑:扩展示例数据和结果以避免混淆。


我实际需要开发的查询要复杂得多。我只是认为这会让我在其中一个逻辑障碍上有一个良好的开端。因为我知道每个人都会想知道我尝试了什么,所以这里是我当前的、令人尴尬的、来自实际结构的迭代...

SELECT 
        SessionId,
        SAMLData_Organization, 
        (Select TimeCreated FROM ens.messageheader h1,HS_Message.XMLMessage m1 WHERE h1.SessionId = h3.SessionId and m1.name = 'XDSB_QueryRequest') as RequestRecieved,
        (Select TimeCreated FROM ens.messageheader h1,HS_Message.XMLMessage m1 WHERE h1.SessionId = h3.SessionId and m1.name = 'XDSB_QueryResponse') as ResponseSent
FROM 
        ens.messageheader h3,HS_Message.XMLMessage m3
WHERE SessionId IN (SELECT Distinct SessionId FROM ens.messageheader WHERE TimeCreated >= '2016-08-22 08' AND TimeCreated < '2016-08-22 17')

我要解决的问题:

  1. 加入ENS.MessageHeaderHS_Message.XMLMessage
  2. 获取 XDSb_QueryRequest
  3. 类型消息的 TimeCreated
  4. 使用SessionId作为普通值,得到相应XDSb_QueryResponseTimeCreated值。
  5. Return 结果为 Organization | RequestReceived | ResponseSent

纯 LEFT SELF JOIN 方法

SELECT
    li.Name
    ,li.Timestamp as Login
    ,lo.Timestamp as LogOut
FROM
    TableName li
    LEFT JOIN TableName lo
    ON li.[Session ID] = lo.[Session ID]
    AND lo.Event = 'Logou'
WHERE
    li.Event = 'Login'

带聚合的 LEFT SELF JOIN

SELECT
    li.Name
    ,li.Timestamp as Login
    ,MIN(lo.Timestamp) as LogOut
FROM
    TableName li
    LEFT JOIN TableName lo
    ON li.Name = lo.Name
    AND lo.Timestamp > li.Timestamp
    AND lo.Event = 'Logou'
WHERE
    li.Event = 'Login'
GROUP BY
    li.Name
    ,li.Timestamp

顶部的很好,因为它限制了每个 SessionId,因此您可以看到每个会话的外观。如果会话 ID 对于您要查找的名称和 login/logout 对不是唯一的,则底部效果很好。

根据你的回答应该也可以这样写:

SELECT
    li.SAMLData_Organization,
    li.SessionId,
    m1.TimeCreated as RequestRecieved,
    m2.TimeCreated as ResponseSent
FROM
    ens.messageheader h1
    INNER JOIN HS_Message.XMLMessage m1
    ON h1.MessageBodyId = m1.id
    and m1.name = 'XDSb_RetrieveRequest'
    LEFT JOIN HS_Message.XMLMessage m2
    ON h1.MessageBodyId = m2.id
    and m2.name = 'XDSb_RetrieveResponse'
ORDER BY
    h1.SessionId DESC

你可以这样做,把所有东西都分解成碎片,然后把它们放在一起,我假设你有一个 id 列

select distinct name, id, 

(SELECT min(timestamp) from table
where event = "login" and user_id = event_table.user_id) as login,

(SELECT max (timestamp) from table
where event = "logout" and user_id = event_table.user_id) as logout

from event_table 

希望你明白这对你有帮助

根据@Matt 的回答,这是我的实际查询:

SELECT
        li.SAMLData_Organization,
        li.SessionId,
        li.TimeCreated as RequestRecieved,
        lo.TimeCreated as ResponseSent
FROM
    (Select h1.SessionId, TimeCreated, SAMLData_Organization FROM ens.messageheader h1,HS_Message.XMLMessage m1 WHERE h1.MessageBodyId = m1.id and m1.name = 'XDSb_RetrieveRequest') li
    LEFT JOIN (Select h2.SessionId, TimeCreated FROM ens.messageheader h2,HS_Message.XMLMessage m2 WHERE h2.MessageBodyId = m2.id and m2.name = 'XDSb_RetrieveResponse') lo
    ON li.SessionId = lo.SessionId
GROUP BY li.SessionId
ORDER BY li.SessionId Desc