SQL Group By within some time frame
I need to group by id, status within some timestamp.
for example I have this table:
id | status | time | value | deviceId
1 | true | 10:31 | 1 | 5
2 | true | 10:32 | 2 | 5
3 | true | 10:33 | 3 | 5
4 | false | 10:34 | 3 | 5
5 | false | 10:35 | 4 | 5
6 | false | 10:36 | 5 | 5
7 | true | 10:37 | 4 | 5
8 | true | 10:38 | 5 | 5
9 | true | 10:39 | 6 | 5
Table is ordered by time.
Every group should be for same id, if status is true, within time were status is true.
For same groupId I will need new results when status become true, but this is in another time frame so should be another group.
Based on above example result should be:
deviceId | avg(value)
5 | 2 (average value for rows 1,2,3 for deviceid = 5)
5 | 5 (average value of rows 7,8,9 for deviceid = 5. Same group, but another time frame)
I can group by deviceId and group by status.
SELECT deviceid ,status, AVG(value)
FROM mytable
WHERE status = true
GROUP BY deviceid,status;
But I don't know how to do all that within time frame?
Thank you for your help.
Edit:
I tried to explain what is time frame. Maybe my English is not good enough so I will try again. You can see that time is in order. Table is ordered by time.
Rows 1,2,3 are within time frame while status i true.
In row 4 status is false so this is time when second time frame starts.
Second time frame are rows 4,5,6.
In row 7 status is again true, so here third time frame starts. Third time frame are rows 7,8,9
I just need results of groups where status is true, so only first and third time frame are relevant to me.
sql
|
show 7 more comments
I need to group by id, status within some timestamp.
for example I have this table:
id | status | time | value | deviceId
1 | true | 10:31 | 1 | 5
2 | true | 10:32 | 2 | 5
3 | true | 10:33 | 3 | 5
4 | false | 10:34 | 3 | 5
5 | false | 10:35 | 4 | 5
6 | false | 10:36 | 5 | 5
7 | true | 10:37 | 4 | 5
8 | true | 10:38 | 5 | 5
9 | true | 10:39 | 6 | 5
Table is ordered by time.
Every group should be for same id, if status is true, within time were status is true.
For same groupId I will need new results when status become true, but this is in another time frame so should be another group.
Based on above example result should be:
deviceId | avg(value)
5 | 2 (average value for rows 1,2,3 for deviceid = 5)
5 | 5 (average value of rows 7,8,9 for deviceid = 5. Same group, but another time frame)
I can group by deviceId and group by status.
SELECT deviceid ,status, AVG(value)
FROM mytable
WHERE status = true
GROUP BY deviceid,status;
But I don't know how to do all that within time frame?
Thank you for your help.
Edit:
I tried to explain what is time frame. Maybe my English is not good enough so I will try again. You can see that time is in order. Table is ordered by time.
Rows 1,2,3 are within time frame while status i true.
In row 4 status is false so this is time when second time frame starts.
Second time frame are rows 4,5,6.
In row 7 status is again true, so here third time frame starts. Third time frame are rows 7,8,9
I just need results of groups where status is true, so only first and third time frame are relevant to me.
sql
2
1,2,3 and 7,8,9 are rows, not columns. Also, please define what a timeframe is to you. I just see a bunch of different times, and I don't see how some of them belong together and others don't.
– GolezTrol
Nov 13 '18 at 10:37
What is the type of the time column?
– majidarif
Nov 13 '18 at 10:38
@majidarif Timestamp
– Raskolnikov
Nov 13 '18 at 10:40
Time cannot be hardcoded. It should work for any time frame. I could have 1000 time frames.
– Raskolnikov
Nov 13 '18 at 10:49
SQL is just a language, what rdbms are you working with? Please edit your question to include the rdbms product tag as well as the specific version tag.
– Zohar Peled
Nov 13 '18 at 10:49
|
show 7 more comments
I need to group by id, status within some timestamp.
for example I have this table:
id | status | time | value | deviceId
1 | true | 10:31 | 1 | 5
2 | true | 10:32 | 2 | 5
3 | true | 10:33 | 3 | 5
4 | false | 10:34 | 3 | 5
5 | false | 10:35 | 4 | 5
6 | false | 10:36 | 5 | 5
7 | true | 10:37 | 4 | 5
8 | true | 10:38 | 5 | 5
9 | true | 10:39 | 6 | 5
Table is ordered by time.
Every group should be for same id, if status is true, within time were status is true.
For same groupId I will need new results when status become true, but this is in another time frame so should be another group.
Based on above example result should be:
deviceId | avg(value)
5 | 2 (average value for rows 1,2,3 for deviceid = 5)
5 | 5 (average value of rows 7,8,9 for deviceid = 5. Same group, but another time frame)
I can group by deviceId and group by status.
SELECT deviceid ,status, AVG(value)
FROM mytable
WHERE status = true
GROUP BY deviceid,status;
But I don't know how to do all that within time frame?
Thank you for your help.
Edit:
I tried to explain what is time frame. Maybe my English is not good enough so I will try again. You can see that time is in order. Table is ordered by time.
Rows 1,2,3 are within time frame while status i true.
In row 4 status is false so this is time when second time frame starts.
Second time frame are rows 4,5,6.
In row 7 status is again true, so here third time frame starts. Third time frame are rows 7,8,9
I just need results of groups where status is true, so only first and third time frame are relevant to me.
sql
I need to group by id, status within some timestamp.
for example I have this table:
id | status | time | value | deviceId
1 | true | 10:31 | 1 | 5
2 | true | 10:32 | 2 | 5
3 | true | 10:33 | 3 | 5
4 | false | 10:34 | 3 | 5
5 | false | 10:35 | 4 | 5
6 | false | 10:36 | 5 | 5
7 | true | 10:37 | 4 | 5
8 | true | 10:38 | 5 | 5
9 | true | 10:39 | 6 | 5
Table is ordered by time.
Every group should be for same id, if status is true, within time were status is true.
For same groupId I will need new results when status become true, but this is in another time frame so should be another group.
Based on above example result should be:
deviceId | avg(value)
5 | 2 (average value for rows 1,2,3 for deviceid = 5)
5 | 5 (average value of rows 7,8,9 for deviceid = 5. Same group, but another time frame)
I can group by deviceId and group by status.
SELECT deviceid ,status, AVG(value)
FROM mytable
WHERE status = true
GROUP BY deviceid,status;
But I don't know how to do all that within time frame?
Thank you for your help.
Edit:
I tried to explain what is time frame. Maybe my English is not good enough so I will try again. You can see that time is in order. Table is ordered by time.
Rows 1,2,3 are within time frame while status i true.
In row 4 status is false so this is time when second time frame starts.
Second time frame are rows 4,5,6.
In row 7 status is again true, so here third time frame starts. Third time frame are rows 7,8,9
I just need results of groups where status is true, so only first and third time frame are relevant to me.
sql
sql
edited Nov 13 '18 at 11:57
Gordon Linoff
762k35294399
762k35294399
asked Nov 13 '18 at 10:36
RaskolnikovRaskolnikov
74921851
74921851
2
1,2,3 and 7,8,9 are rows, not columns. Also, please define what a timeframe is to you. I just see a bunch of different times, and I don't see how some of them belong together and others don't.
– GolezTrol
Nov 13 '18 at 10:37
What is the type of the time column?
– majidarif
Nov 13 '18 at 10:38
@majidarif Timestamp
– Raskolnikov
Nov 13 '18 at 10:40
Time cannot be hardcoded. It should work for any time frame. I could have 1000 time frames.
– Raskolnikov
Nov 13 '18 at 10:49
SQL is just a language, what rdbms are you working with? Please edit your question to include the rdbms product tag as well as the specific version tag.
– Zohar Peled
Nov 13 '18 at 10:49
|
show 7 more comments
2
1,2,3 and 7,8,9 are rows, not columns. Also, please define what a timeframe is to you. I just see a bunch of different times, and I don't see how some of them belong together and others don't.
– GolezTrol
Nov 13 '18 at 10:37
What is the type of the time column?
– majidarif
Nov 13 '18 at 10:38
@majidarif Timestamp
– Raskolnikov
Nov 13 '18 at 10:40
Time cannot be hardcoded. It should work for any time frame. I could have 1000 time frames.
– Raskolnikov
Nov 13 '18 at 10:49
SQL is just a language, what rdbms are you working with? Please edit your question to include the rdbms product tag as well as the specific version tag.
– Zohar Peled
Nov 13 '18 at 10:49
2
2
1,2,3 and 7,8,9 are rows, not columns. Also, please define what a timeframe is to you. I just see a bunch of different times, and I don't see how some of them belong together and others don't.
– GolezTrol
Nov 13 '18 at 10:37
1,2,3 and 7,8,9 are rows, not columns. Also, please define what a timeframe is to you. I just see a bunch of different times, and I don't see how some of them belong together and others don't.
– GolezTrol
Nov 13 '18 at 10:37
What is the type of the time column?
– majidarif
Nov 13 '18 at 10:38
What is the type of the time column?
– majidarif
Nov 13 '18 at 10:38
@majidarif Timestamp
– Raskolnikov
Nov 13 '18 at 10:40
@majidarif Timestamp
– Raskolnikov
Nov 13 '18 at 10:40
Time cannot be hardcoded. It should work for any time frame. I could have 1000 time frames.
– Raskolnikov
Nov 13 '18 at 10:49
Time cannot be hardcoded. It should work for any time frame. I could have 1000 time frames.
– Raskolnikov
Nov 13 '18 at 10:49
SQL is just a language, what rdbms are you working with? Please edit your question to include the rdbms product tag as well as the specific version tag.
– Zohar Peled
Nov 13 '18 at 10:49
SQL is just a language, what rdbms are you working with? Please edit your question to include the rdbms product tag as well as the specific version tag.
– Zohar Peled
Nov 13 '18 at 10:49
|
show 7 more comments
1 Answer
1
active
oldest
votes
You can determine the groups of "true"s by doing a cumulative count of "false"s. This count will be constant for a group of consecutive "true"s.
The rest is then just filtering and aggregation:
select deviceid, grp, avg(value)
from (select t.*,
sum(case when status = 'false' then 1 else 0 end) over (partition by deviceid order by time) as grp
from t
) t
where status = 'true'
group by deviceid, grp;
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%2f53279099%2fsql-group-by-within-some-time-frame%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can determine the groups of "true"s by doing a cumulative count of "false"s. This count will be constant for a group of consecutive "true"s.
The rest is then just filtering and aggregation:
select deviceid, grp, avg(value)
from (select t.*,
sum(case when status = 'false' then 1 else 0 end) over (partition by deviceid order by time) as grp
from t
) t
where status = 'true'
group by deviceid, grp;
add a comment |
You can determine the groups of "true"s by doing a cumulative count of "false"s. This count will be constant for a group of consecutive "true"s.
The rest is then just filtering and aggregation:
select deviceid, grp, avg(value)
from (select t.*,
sum(case when status = 'false' then 1 else 0 end) over (partition by deviceid order by time) as grp
from t
) t
where status = 'true'
group by deviceid, grp;
add a comment |
You can determine the groups of "true"s by doing a cumulative count of "false"s. This count will be constant for a group of consecutive "true"s.
The rest is then just filtering and aggregation:
select deviceid, grp, avg(value)
from (select t.*,
sum(case when status = 'false' then 1 else 0 end) over (partition by deviceid order by time) as grp
from t
) t
where status = 'true'
group by deviceid, grp;
You can determine the groups of "true"s by doing a cumulative count of "false"s. This count will be constant for a group of consecutive "true"s.
The rest is then just filtering and aggregation:
select deviceid, grp, avg(value)
from (select t.*,
sum(case when status = 'false' then 1 else 0 end) over (partition by deviceid order by time) as grp
from t
) t
where status = 'true'
group by deviceid, grp;
answered Nov 13 '18 at 12:04
Gordon LinoffGordon Linoff
762k35294399
762k35294399
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%2f53279099%2fsql-group-by-within-some-time-frame%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
2
1,2,3 and 7,8,9 are rows, not columns. Also, please define what a timeframe is to you. I just see a bunch of different times, and I don't see how some of them belong together and others don't.
– GolezTrol
Nov 13 '18 at 10:37
What is the type of the time column?
– majidarif
Nov 13 '18 at 10:38
@majidarif Timestamp
– Raskolnikov
Nov 13 '18 at 10:40
Time cannot be hardcoded. It should work for any time frame. I could have 1000 time frames.
– Raskolnikov
Nov 13 '18 at 10:49
SQL is just a language, what rdbms are you working with? Please edit your question to include the rdbms product tag as well as the specific version tag.
– Zohar Peled
Nov 13 '18 at 10:49