Reputation:
Given the following data, how would I get the desired result below?
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
Desired Result (essentially a list of session durations):
Name | Login | Logout
------------------------
Scott | 8:15 | 8:23
John | 8:16 | 8:28
Scott | 8:30 | 8:37
edit: extended sample data and results to avoid some confusion.
The query I'm actually needing to develop is much more complex . I just thought this would give me a good jumpstart on one of the logic hurdles. Since I know everyone will want to know what I've tried, here is my current, embarrassing, iteration from the actual structure...
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')
Things I'm trying to tackle:
ENS.MessageHeader
and HS_Message.XMLMessage
TimeCreated
value for messages of type XDSb_QueryRequest
TimeCreated
value for the corresponding XDSb_QueryResponse
using the SessionId
as a common value.Organization | RequestReceived | ResponseSent
Upvotes: 2
Views: 90
Reputation: 14361
Pure LEFT SELF JOIN method
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 with aggregation
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
The top one is good because it constrains per SessionId so you can see a per session look. The bottom works well if session Id is not unique to the name and login/logout pair you are looking for.
Per your answer it should be able to be written like this as well:
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
Upvotes: 2
Reputation:
Based on @Matt's answer, here is my actual query:
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
Upvotes: 0
Reputation: 105
You can do something like this, just break everything down into pieces and then put them together, I assumed you have an id column
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
Hope you understand and this helps
Upvotes: -2