MySQL Get records having a time difference with other records
I have a MySQL DB table that logs user login and logout activities.
I need to select all user records who are not logged back in within 20 minutes after logout.
Ex: Table: Log
ID | User | Event | Time
-----------------------------
1 | 1 | LOGIN | 10:00:00
2 | 2 | LOGIN | 10:05:00
3 | 3 | LOGIN | 10:15:00
4 | 1 | LOGOUT | 11:00:00
5 | 3 | LOGOUT | 11:01:00
6 | 2 | LOGIN | 12:20:00
7 | 2 | LOGOUT | 12:30:00
8 | 1 | LOGIN | 12:31:00
9 | 2 | LOGIN | 12:55:00
According to this sample table, the users that exceeds the gap by 20 minutes between their logouts and logins must be shown.
User 1 exceeds the 20 minute gap between record 4 and 8
User 2 exceeds the 20 minute gap between record 7 and 9
So this should show
ID | User
----------
4 | 1
8 | 1
7 | 2
9 | 2
How can I write a query to get this done?
mysql sql time
add a comment |
I have a MySQL DB table that logs user login and logout activities.
I need to select all user records who are not logged back in within 20 minutes after logout.
Ex: Table: Log
ID | User | Event | Time
-----------------------------
1 | 1 | LOGIN | 10:00:00
2 | 2 | LOGIN | 10:05:00
3 | 3 | LOGIN | 10:15:00
4 | 1 | LOGOUT | 11:00:00
5 | 3 | LOGOUT | 11:01:00
6 | 2 | LOGIN | 12:20:00
7 | 2 | LOGOUT | 12:30:00
8 | 1 | LOGIN | 12:31:00
9 | 2 | LOGIN | 12:55:00
According to this sample table, the users that exceeds the gap by 20 minutes between their logouts and logins must be shown.
User 1 exceeds the 20 minute gap between record 4 and 8
User 2 exceeds the 20 minute gap between record 7 and 9
So this should show
ID | User
----------
4 | 1
8 | 1
7 | 2
9 | 2
How can I write a query to get this done?
mysql sql time
If you really need to check every login/logout event for this, then your problem is a gaps and islands problem. This is difficult to solve, especially if you are using MySQL versions earlier than 8.
– Tim Biegeleisen
Nov 23 '18 at 10:41
add a comment |
I have a MySQL DB table that logs user login and logout activities.
I need to select all user records who are not logged back in within 20 minutes after logout.
Ex: Table: Log
ID | User | Event | Time
-----------------------------
1 | 1 | LOGIN | 10:00:00
2 | 2 | LOGIN | 10:05:00
3 | 3 | LOGIN | 10:15:00
4 | 1 | LOGOUT | 11:00:00
5 | 3 | LOGOUT | 11:01:00
6 | 2 | LOGIN | 12:20:00
7 | 2 | LOGOUT | 12:30:00
8 | 1 | LOGIN | 12:31:00
9 | 2 | LOGIN | 12:55:00
According to this sample table, the users that exceeds the gap by 20 minutes between their logouts and logins must be shown.
User 1 exceeds the 20 minute gap between record 4 and 8
User 2 exceeds the 20 minute gap between record 7 and 9
So this should show
ID | User
----------
4 | 1
8 | 1
7 | 2
9 | 2
How can I write a query to get this done?
mysql sql time
I have a MySQL DB table that logs user login and logout activities.
I need to select all user records who are not logged back in within 20 minutes after logout.
Ex: Table: Log
ID | User | Event | Time
-----------------------------
1 | 1 | LOGIN | 10:00:00
2 | 2 | LOGIN | 10:05:00
3 | 3 | LOGIN | 10:15:00
4 | 1 | LOGOUT | 11:00:00
5 | 3 | LOGOUT | 11:01:00
6 | 2 | LOGIN | 12:20:00
7 | 2 | LOGOUT | 12:30:00
8 | 1 | LOGIN | 12:31:00
9 | 2 | LOGIN | 12:55:00
According to this sample table, the users that exceeds the gap by 20 minutes between their logouts and logins must be shown.
User 1 exceeds the 20 minute gap between record 4 and 8
User 2 exceeds the 20 minute gap between record 7 and 9
So this should show
ID | User
----------
4 | 1
8 | 1
7 | 2
9 | 2
How can I write a query to get this done?
mysql sql time
mysql sql time
edited Nov 26 '18 at 11:51
Salman A
185k67344441
185k67344441
asked Nov 23 '18 at 10:19
TechyTeeTechyTee
82121130
82121130
If you really need to check every login/logout event for this, then your problem is a gaps and islands problem. This is difficult to solve, especially if you are using MySQL versions earlier than 8.
– Tim Biegeleisen
Nov 23 '18 at 10:41
add a comment |
If you really need to check every login/logout event for this, then your problem is a gaps and islands problem. This is difficult to solve, especially if you are using MySQL versions earlier than 8.
– Tim Biegeleisen
Nov 23 '18 at 10:41
If you really need to check every login/logout event for this, then your problem is a gaps and islands problem. This is difficult to solve, especially if you are using MySQL versions earlier than 8.
– Tim Biegeleisen
Nov 23 '18 at 10:41
If you really need to check every login/logout event for this, then your problem is a gaps and islands problem. This is difficult to solve, especially if you are using MySQL versions earlier than 8.
– Tim Biegeleisen
Nov 23 '18 at 10:41
add a comment |
2 Answers
2
active
oldest
votes
This answers the question:
I need to select all user records who are not logged back in within 20 minutes after logout.
select lo.*
from (select l.*,
(select min(l2.time)
from logs l2
where l2.user = l.user and l2.time > l.time and
l2.event = 'LOGIN'
) as next_login_time
from logs l
where l.event = 'LOGOUT'
) lo
where next_login_time > time + interval 20 minute;
Your sample results include login results. It is unclear how those are defined, based on the question that you asked.
add a comment |
You seem to be interested in getting both rows if they are 20 minutes apart. The following tries to emulate LEAD and LAG:
SELECT * FROM (
SELECT *, (
SELECT CASE WHEN EVENT = 'LOGOUT' AND main.Event = 'LOGIN' THEN TimeDIFF(main.Time, Time) END
FROM t AS prev
WHERE User = main.User AND Time < main.Time
ORDER BY Time DESC
LIMIT 1
) AS diff_lag, (
SELECT CASE WHEN EVENT = 'LOGIN' AND main.Event = 'LOGOUT' THEN TimeDIFF(Time, main.Time) END
FROM t AS next
WHERE User = main.User AND Time > main.Time
ORDER BY Time ASC
LIMIT 1
) AS diff_lead
FROM t AS main
) x
WHERE diff_lag > '00:20:00' OR diff_lead > '00:20:00'
Alternatively, try the following approach which seems to work except that it puts both rows together:
SELECT *
FROM t AS o
INNER JOIN t AS i ON o.User = i.User AND o.Time < i.Time -- join logouts with potential logins
LEFT JOIN t AS x ON o.User = x.User AND o.Time < x.Time AND x.Time < i.Time -- any row present between logout and login
WHERE o.Event = 'LOGOUT' AND i.Event = 'LOGIN' AND x.ID IS NULL AND TIMEDIFF(i.Time, o.Time) > '00:20:00'
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444778%2fmysql-get-records-having-a-time-difference-with-other-records%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
This answers the question:
I need to select all user records who are not logged back in within 20 minutes after logout.
select lo.*
from (select l.*,
(select min(l2.time)
from logs l2
where l2.user = l.user and l2.time > l.time and
l2.event = 'LOGIN'
) as next_login_time
from logs l
where l.event = 'LOGOUT'
) lo
where next_login_time > time + interval 20 minute;
Your sample results include login results. It is unclear how those are defined, based on the question that you asked.
add a comment |
This answers the question:
I need to select all user records who are not logged back in within 20 minutes after logout.
select lo.*
from (select l.*,
(select min(l2.time)
from logs l2
where l2.user = l.user and l2.time > l.time and
l2.event = 'LOGIN'
) as next_login_time
from logs l
where l.event = 'LOGOUT'
) lo
where next_login_time > time + interval 20 minute;
Your sample results include login results. It is unclear how those are defined, based on the question that you asked.
add a comment |
This answers the question:
I need to select all user records who are not logged back in within 20 minutes after logout.
select lo.*
from (select l.*,
(select min(l2.time)
from logs l2
where l2.user = l.user and l2.time > l.time and
l2.event = 'LOGIN'
) as next_login_time
from logs l
where l.event = 'LOGOUT'
) lo
where next_login_time > time + interval 20 minute;
Your sample results include login results. It is unclear how those are defined, based on the question that you asked.
This answers the question:
I need to select all user records who are not logged back in within 20 minutes after logout.
select lo.*
from (select l.*,
(select min(l2.time)
from logs l2
where l2.user = l.user and l2.time > l.time and
l2.event = 'LOGIN'
) as next_login_time
from logs l
where l.event = 'LOGOUT'
) lo
where next_login_time > time + interval 20 minute;
Your sample results include login results. It is unclear how those are defined, based on the question that you asked.
answered Nov 23 '18 at 12:21
Gordon LinoffGordon Linoff
792k36316419
792k36316419
add a comment |
add a comment |
You seem to be interested in getting both rows if they are 20 minutes apart. The following tries to emulate LEAD and LAG:
SELECT * FROM (
SELECT *, (
SELECT CASE WHEN EVENT = 'LOGOUT' AND main.Event = 'LOGIN' THEN TimeDIFF(main.Time, Time) END
FROM t AS prev
WHERE User = main.User AND Time < main.Time
ORDER BY Time DESC
LIMIT 1
) AS diff_lag, (
SELECT CASE WHEN EVENT = 'LOGIN' AND main.Event = 'LOGOUT' THEN TimeDIFF(Time, main.Time) END
FROM t AS next
WHERE User = main.User AND Time > main.Time
ORDER BY Time ASC
LIMIT 1
) AS diff_lead
FROM t AS main
) x
WHERE diff_lag > '00:20:00' OR diff_lead > '00:20:00'
Alternatively, try the following approach which seems to work except that it puts both rows together:
SELECT *
FROM t AS o
INNER JOIN t AS i ON o.User = i.User AND o.Time < i.Time -- join logouts with potential logins
LEFT JOIN t AS x ON o.User = x.User AND o.Time < x.Time AND x.Time < i.Time -- any row present between logout and login
WHERE o.Event = 'LOGOUT' AND i.Event = 'LOGIN' AND x.ID IS NULL AND TIMEDIFF(i.Time, o.Time) > '00:20:00'
add a comment |
You seem to be interested in getting both rows if they are 20 minutes apart. The following tries to emulate LEAD and LAG:
SELECT * FROM (
SELECT *, (
SELECT CASE WHEN EVENT = 'LOGOUT' AND main.Event = 'LOGIN' THEN TimeDIFF(main.Time, Time) END
FROM t AS prev
WHERE User = main.User AND Time < main.Time
ORDER BY Time DESC
LIMIT 1
) AS diff_lag, (
SELECT CASE WHEN EVENT = 'LOGIN' AND main.Event = 'LOGOUT' THEN TimeDIFF(Time, main.Time) END
FROM t AS next
WHERE User = main.User AND Time > main.Time
ORDER BY Time ASC
LIMIT 1
) AS diff_lead
FROM t AS main
) x
WHERE diff_lag > '00:20:00' OR diff_lead > '00:20:00'
Alternatively, try the following approach which seems to work except that it puts both rows together:
SELECT *
FROM t AS o
INNER JOIN t AS i ON o.User = i.User AND o.Time < i.Time -- join logouts with potential logins
LEFT JOIN t AS x ON o.User = x.User AND o.Time < x.Time AND x.Time < i.Time -- any row present between logout and login
WHERE o.Event = 'LOGOUT' AND i.Event = 'LOGIN' AND x.ID IS NULL AND TIMEDIFF(i.Time, o.Time) > '00:20:00'
add a comment |
You seem to be interested in getting both rows if they are 20 minutes apart. The following tries to emulate LEAD and LAG:
SELECT * FROM (
SELECT *, (
SELECT CASE WHEN EVENT = 'LOGOUT' AND main.Event = 'LOGIN' THEN TimeDIFF(main.Time, Time) END
FROM t AS prev
WHERE User = main.User AND Time < main.Time
ORDER BY Time DESC
LIMIT 1
) AS diff_lag, (
SELECT CASE WHEN EVENT = 'LOGIN' AND main.Event = 'LOGOUT' THEN TimeDIFF(Time, main.Time) END
FROM t AS next
WHERE User = main.User AND Time > main.Time
ORDER BY Time ASC
LIMIT 1
) AS diff_lead
FROM t AS main
) x
WHERE diff_lag > '00:20:00' OR diff_lead > '00:20:00'
Alternatively, try the following approach which seems to work except that it puts both rows together:
SELECT *
FROM t AS o
INNER JOIN t AS i ON o.User = i.User AND o.Time < i.Time -- join logouts with potential logins
LEFT JOIN t AS x ON o.User = x.User AND o.Time < x.Time AND x.Time < i.Time -- any row present between logout and login
WHERE o.Event = 'LOGOUT' AND i.Event = 'LOGIN' AND x.ID IS NULL AND TIMEDIFF(i.Time, o.Time) > '00:20:00'
You seem to be interested in getting both rows if they are 20 minutes apart. The following tries to emulate LEAD and LAG:
SELECT * FROM (
SELECT *, (
SELECT CASE WHEN EVENT = 'LOGOUT' AND main.Event = 'LOGIN' THEN TimeDIFF(main.Time, Time) END
FROM t AS prev
WHERE User = main.User AND Time < main.Time
ORDER BY Time DESC
LIMIT 1
) AS diff_lag, (
SELECT CASE WHEN EVENT = 'LOGIN' AND main.Event = 'LOGOUT' THEN TimeDIFF(Time, main.Time) END
FROM t AS next
WHERE User = main.User AND Time > main.Time
ORDER BY Time ASC
LIMIT 1
) AS diff_lead
FROM t AS main
) x
WHERE diff_lag > '00:20:00' OR diff_lead > '00:20:00'
Alternatively, try the following approach which seems to work except that it puts both rows together:
SELECT *
FROM t AS o
INNER JOIN t AS i ON o.User = i.User AND o.Time < i.Time -- join logouts with potential logins
LEFT JOIN t AS x ON o.User = x.User AND o.Time < x.Time AND x.Time < i.Time -- any row present between logout and login
WHERE o.Event = 'LOGOUT' AND i.Event = 'LOGIN' AND x.ID IS NULL AND TIMEDIFF(i.Time, o.Time) > '00:20:00'
edited Nov 24 '18 at 18:55
answered Nov 23 '18 at 13:16
Salman ASalman A
185k67344441
185k67344441
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444778%2fmysql-get-records-having-a-time-difference-with-other-records%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
If you really need to check every login/logout event for this, then your problem is a gaps and islands problem. This is difficult to solve, especially if you are using MySQL versions earlier than 8.
– Tim Biegeleisen
Nov 23 '18 at 10:41