Show current row “win streak” Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Using Row_Number to find consecutive row countReset password for 'postgres' on v9.3 (Win Srv)Group by maximum consecutive rowMerging adjacent date intervals into a single rowTrigger function using current row and current table name as variablesTrigger function using current row and current table name as variables (final part)Selecting row grouped by an “add-on” indicatorFilter on time difference between current and next rowPostgreSQL: mark current session as “unimportant”How to count max date row if current status column is 0 or 2?
If Windows 7 doesn't support WSL, then what is "Subsystem for UNIX-based Applications"?
Are the endpoints of the domain of a function counted as critical points?
Is openssl rand command cryptographically secure?
New Order #6: Easter Egg
Delete free apps from library
Trying to understand entropy as a novice in thermodynamics
Tips to organize LaTeX presentations for a semester
GDP with Intermediate Production
A proverb that is used to imply that you have unexpectedly faced a big problem
Can you force honesty by using the Speak with Dead and Zone of Truth spells together?
Why is std::move not [[nodiscard]] in C++20?
License to disallow distribution in closed source software, but allow exceptions made by owner?
Would color changing eyes affect vision?
How does light 'choose' between wave and particle behaviour?
Select every other edge (they share a common vertex)
Why are vacuum tubes still used in amateur radios?
What are the main differences between Stargate SG-1 cuts?
Universal covering space of the real projective line?
Flight departed from the gate 5 min before scheduled departure time. Refund options
Moving a wrapfig vertically to encroach partially on a subsection title
Does silver oxide react with hydrogen sulfide?
Special flights
AppleTVs create a chatty alternate WiFi network
The test team as an enemy of development? And how can this be avoided?
Show current row “win streak”
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Using Row_Number to find consecutive row countReset password for 'postgres' on v9.3 (Win Srv)Group by maximum consecutive rowMerging adjacent date intervals into a single rowTrigger function using current row and current table name as variablesTrigger function using current row and current table name as variables (final part)Selecting row grouped by an “add-on” indicatorFilter on time difference between current and next rowPostgreSQL: mark current session as “unimportant”How to count max date row if current status column is 0 or 2?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I need to show the running win/loss streak per row in a query, so given the table below, the query should return the "expected" column. I've tried some approaches with window functions, but no success.
create table matches (player text, dt date, is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, 0);
player dt is_winner expected
A 2019-01-01 true 0
A 2019-01-03 true 1
A 2019-01-04 true 2
A 2019-01-09 false 0
A 2019-01-10 false -1
A 2019-01-15 true 0
The logic is:
- Resets to 0 when winning after a loss, or losing after a win.
- Increments after a win, but not if it's case 1.
- Decrements after a loss, but not if it's case 1.
Any insights on how to tackle this are welcome. My last resort would be a function with a loop called by every row.
postgresql gaps-and-islands
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
I need to show the running win/loss streak per row in a query, so given the table below, the query should return the "expected" column. I've tried some approaches with window functions, but no success.
create table matches (player text, dt date, is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, 0);
player dt is_winner expected
A 2019-01-01 true 0
A 2019-01-03 true 1
A 2019-01-04 true 2
A 2019-01-09 false 0
A 2019-01-10 false -1
A 2019-01-15 true 0
The logic is:
- Resets to 0 when winning after a loss, or losing after a win.
- Increments after a win, but not if it's case 1.
- Decrements after a loss, but not if it's case 1.
Any insights on how to tackle this are welcome. My last resort would be a function with a loop called by every row.
postgresql gaps-and-islands
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
I need to show the running win/loss streak per row in a query, so given the table below, the query should return the "expected" column. I've tried some approaches with window functions, but no success.
create table matches (player text, dt date, is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, 0);
player dt is_winner expected
A 2019-01-01 true 0
A 2019-01-03 true 1
A 2019-01-04 true 2
A 2019-01-09 false 0
A 2019-01-10 false -1
A 2019-01-15 true 0
The logic is:
- Resets to 0 when winning after a loss, or losing after a win.
- Increments after a win, but not if it's case 1.
- Decrements after a loss, but not if it's case 1.
Any insights on how to tackle this are welcome. My last resort would be a function with a loop called by every row.
postgresql gaps-and-islands
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I need to show the running win/loss streak per row in a query, so given the table below, the query should return the "expected" column. I've tried some approaches with window functions, but no success.
create table matches (player text, dt date, is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, 0);
player dt is_winner expected
A 2019-01-01 true 0
A 2019-01-03 true 1
A 2019-01-04 true 2
A 2019-01-09 false 0
A 2019-01-10 false -1
A 2019-01-15 true 0
The logic is:
- Resets to 0 when winning after a loss, or losing after a win.
- Increments after a win, but not if it's case 1.
- Decrements after a loss, but not if it's case 1.
Any insights on how to tackle this are welcome. My last resort would be a function with a loop called by every row.
postgresql gaps-and-islands
postgresql gaps-and-islands
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 3 hours ago
Paul White♦
54.3k14288461
54.3k14288461
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 10 hours ago
codigofontescodigofontes
183
183
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
codigofontes is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I've done this in stages using CTEs so that you can see how it's done as the queries progress. Each CTE adds a column in the output in order to show you progress.
It's pretty much self-documenting with the CTE names, to be honest.
with lags as (
select player,
dt,
is_winner,
lag(is_winner) OVER (partition by player ORDER BY dt ASC) as prev_is_winner,
expected
from matches
),
group_changes as (
select lags.*,
case
when prev_is_winner <> is_winner or prev_is_winner is null
then 1
else 0
end as is_new_group
from lags
),
groups_numbered as (
select *,
sum(is_new_group)
over (partition by player order by dt, is_winner desc) as streak_group
from group_changes
),
expected_in_groups as (
select groups_numbered.*,
row_number()
over (partition by player,streak_group
order by dt asc, streak_group asc) - 1 as expected_unsigned
from groups_numbered
)
select expected_in_groups.*, case when is_winner = 't' then expected_unsigned else expected_unsigned * -1 end as actual
from expected_in_groups
order by player asc, dt asc;
DB Fiddle Link (I added an extra row just to make sure it was working at a certain point)
Basically:
lagsCTE: useLAG()to get the previous result relative to the current row.group_changesCTE: Detect whether the previous streak, whether win or loss, has endedgroups_numberedCTE: Give each streak a numberexpected_in_groupsCTE: Number the rows in the group- Final
select: negate the loss streaks
.
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| player | dt | is_winner | prev_is_winner | expected | is_new_group | streak_group | expected_unsigned | actual |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| A | 2019-01-01 | t | | 0 | 1 | 1 | 0 | 0 |
| A | 2019-01-03 | t | t | 1 | 0 | 1 | 1 | 1 |
| A | 2019-01-04 | t | t | 2 | 0 | 1 | 2 | 2 |
| A | 2019-01-09 | f | t | 0 | 1 | 2 | 0 | 0 |
| A | 2019-01-10 | f | f | -1 | 0 | 2 | 1 | -1 |
| A | 2019-01-11 | f | f | -2 | 0 | 2 | 2 | -2 |
| A | 2019-01-15 | t | f | 0 | 1 | 3 | 0 | 0 |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "182"
;
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
);
);
codigofontes is a new contributor. Be nice, and check out our Code of Conduct.
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%2fdba.stackexchange.com%2fquestions%2f235306%2fshow-current-row-win-streak%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
I've done this in stages using CTEs so that you can see how it's done as the queries progress. Each CTE adds a column in the output in order to show you progress.
It's pretty much self-documenting with the CTE names, to be honest.
with lags as (
select player,
dt,
is_winner,
lag(is_winner) OVER (partition by player ORDER BY dt ASC) as prev_is_winner,
expected
from matches
),
group_changes as (
select lags.*,
case
when prev_is_winner <> is_winner or prev_is_winner is null
then 1
else 0
end as is_new_group
from lags
),
groups_numbered as (
select *,
sum(is_new_group)
over (partition by player order by dt, is_winner desc) as streak_group
from group_changes
),
expected_in_groups as (
select groups_numbered.*,
row_number()
over (partition by player,streak_group
order by dt asc, streak_group asc) - 1 as expected_unsigned
from groups_numbered
)
select expected_in_groups.*, case when is_winner = 't' then expected_unsigned else expected_unsigned * -1 end as actual
from expected_in_groups
order by player asc, dt asc;
DB Fiddle Link (I added an extra row just to make sure it was working at a certain point)
Basically:
lagsCTE: useLAG()to get the previous result relative to the current row.group_changesCTE: Detect whether the previous streak, whether win or loss, has endedgroups_numberedCTE: Give each streak a numberexpected_in_groupsCTE: Number the rows in the group- Final
select: negate the loss streaks
.
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| player | dt | is_winner | prev_is_winner | expected | is_new_group | streak_group | expected_unsigned | actual |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| A | 2019-01-01 | t | | 0 | 1 | 1 | 0 | 0 |
| A | 2019-01-03 | t | t | 1 | 0 | 1 | 1 | 1 |
| A | 2019-01-04 | t | t | 2 | 0 | 1 | 2 | 2 |
| A | 2019-01-09 | f | t | 0 | 1 | 2 | 0 | 0 |
| A | 2019-01-10 | f | f | -1 | 0 | 2 | 1 | -1 |
| A | 2019-01-11 | f | f | -2 | 0 | 2 | 2 | -2 |
| A | 2019-01-15 | t | f | 0 | 1 | 3 | 0 | 0 |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
add a comment |
I've done this in stages using CTEs so that you can see how it's done as the queries progress. Each CTE adds a column in the output in order to show you progress.
It's pretty much self-documenting with the CTE names, to be honest.
with lags as (
select player,
dt,
is_winner,
lag(is_winner) OVER (partition by player ORDER BY dt ASC) as prev_is_winner,
expected
from matches
),
group_changes as (
select lags.*,
case
when prev_is_winner <> is_winner or prev_is_winner is null
then 1
else 0
end as is_new_group
from lags
),
groups_numbered as (
select *,
sum(is_new_group)
over (partition by player order by dt, is_winner desc) as streak_group
from group_changes
),
expected_in_groups as (
select groups_numbered.*,
row_number()
over (partition by player,streak_group
order by dt asc, streak_group asc) - 1 as expected_unsigned
from groups_numbered
)
select expected_in_groups.*, case when is_winner = 't' then expected_unsigned else expected_unsigned * -1 end as actual
from expected_in_groups
order by player asc, dt asc;
DB Fiddle Link (I added an extra row just to make sure it was working at a certain point)
Basically:
lagsCTE: useLAG()to get the previous result relative to the current row.group_changesCTE: Detect whether the previous streak, whether win or loss, has endedgroups_numberedCTE: Give each streak a numberexpected_in_groupsCTE: Number the rows in the group- Final
select: negate the loss streaks
.
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| player | dt | is_winner | prev_is_winner | expected | is_new_group | streak_group | expected_unsigned | actual |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| A | 2019-01-01 | t | | 0 | 1 | 1 | 0 | 0 |
| A | 2019-01-03 | t | t | 1 | 0 | 1 | 1 | 1 |
| A | 2019-01-04 | t | t | 2 | 0 | 1 | 2 | 2 |
| A | 2019-01-09 | f | t | 0 | 1 | 2 | 0 | 0 |
| A | 2019-01-10 | f | f | -1 | 0 | 2 | 1 | -1 |
| A | 2019-01-11 | f | f | -2 | 0 | 2 | 2 | -2 |
| A | 2019-01-15 | t | f | 0 | 1 | 3 | 0 | 0 |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
add a comment |
I've done this in stages using CTEs so that you can see how it's done as the queries progress. Each CTE adds a column in the output in order to show you progress.
It's pretty much self-documenting with the CTE names, to be honest.
with lags as (
select player,
dt,
is_winner,
lag(is_winner) OVER (partition by player ORDER BY dt ASC) as prev_is_winner,
expected
from matches
),
group_changes as (
select lags.*,
case
when prev_is_winner <> is_winner or prev_is_winner is null
then 1
else 0
end as is_new_group
from lags
),
groups_numbered as (
select *,
sum(is_new_group)
over (partition by player order by dt, is_winner desc) as streak_group
from group_changes
),
expected_in_groups as (
select groups_numbered.*,
row_number()
over (partition by player,streak_group
order by dt asc, streak_group asc) - 1 as expected_unsigned
from groups_numbered
)
select expected_in_groups.*, case when is_winner = 't' then expected_unsigned else expected_unsigned * -1 end as actual
from expected_in_groups
order by player asc, dt asc;
DB Fiddle Link (I added an extra row just to make sure it was working at a certain point)
Basically:
lagsCTE: useLAG()to get the previous result relative to the current row.group_changesCTE: Detect whether the previous streak, whether win or loss, has endedgroups_numberedCTE: Give each streak a numberexpected_in_groupsCTE: Number the rows in the group- Final
select: negate the loss streaks
.
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| player | dt | is_winner | prev_is_winner | expected | is_new_group | streak_group | expected_unsigned | actual |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| A | 2019-01-01 | t | | 0 | 1 | 1 | 0 | 0 |
| A | 2019-01-03 | t | t | 1 | 0 | 1 | 1 | 1 |
| A | 2019-01-04 | t | t | 2 | 0 | 1 | 2 | 2 |
| A | 2019-01-09 | f | t | 0 | 1 | 2 | 0 | 0 |
| A | 2019-01-10 | f | f | -1 | 0 | 2 | 1 | -1 |
| A | 2019-01-11 | f | f | -2 | 0 | 2 | 2 | -2 |
| A | 2019-01-15 | t | f | 0 | 1 | 3 | 0 | 0 |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
I've done this in stages using CTEs so that you can see how it's done as the queries progress. Each CTE adds a column in the output in order to show you progress.
It's pretty much self-documenting with the CTE names, to be honest.
with lags as (
select player,
dt,
is_winner,
lag(is_winner) OVER (partition by player ORDER BY dt ASC) as prev_is_winner,
expected
from matches
),
group_changes as (
select lags.*,
case
when prev_is_winner <> is_winner or prev_is_winner is null
then 1
else 0
end as is_new_group
from lags
),
groups_numbered as (
select *,
sum(is_new_group)
over (partition by player order by dt, is_winner desc) as streak_group
from group_changes
),
expected_in_groups as (
select groups_numbered.*,
row_number()
over (partition by player,streak_group
order by dt asc, streak_group asc) - 1 as expected_unsigned
from groups_numbered
)
select expected_in_groups.*, case when is_winner = 't' then expected_unsigned else expected_unsigned * -1 end as actual
from expected_in_groups
order by player asc, dt asc;
DB Fiddle Link (I added an extra row just to make sure it was working at a certain point)
Basically:
lagsCTE: useLAG()to get the previous result relative to the current row.group_changesCTE: Detect whether the previous streak, whether win or loss, has endedgroups_numberedCTE: Give each streak a numberexpected_in_groupsCTE: Number the rows in the group- Final
select: negate the loss streaks
.
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| player | dt | is_winner | prev_is_winner | expected | is_new_group | streak_group | expected_unsigned | actual |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
| A | 2019-01-01 | t | | 0 | 1 | 1 | 0 | 0 |
| A | 2019-01-03 | t | t | 1 | 0 | 1 | 1 | 1 |
| A | 2019-01-04 | t | t | 2 | 0 | 1 | 2 | 2 |
| A | 2019-01-09 | f | t | 0 | 1 | 2 | 0 | 0 |
| A | 2019-01-10 | f | f | -1 | 0 | 2 | 1 | -1 |
| A | 2019-01-11 | f | f | -2 | 0 | 2 | 2 | -2 |
| A | 2019-01-15 | t | f | 0 | 1 | 3 | 0 | 0 |
+--------+------------+-----------+----------------+----------+--------------+--------------+-------------------+--------+
edited 7 hours ago
answered 7 hours ago
PhilᵀᴹPhilᵀᴹ
25.9k65691
25.9k65691
add a comment |
add a comment |
codigofontes is a new contributor. Be nice, and check out our Code of Conduct.
codigofontes is a new contributor. Be nice, and check out our Code of Conduct.
codigofontes is a new contributor. Be nice, and check out our Code of Conduct.
codigofontes is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Database Administrators Stack Exchange!
- 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%2fdba.stackexchange.com%2fquestions%2f235306%2fshow-current-row-win-streak%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