I have some data:
period | id_account | float_value
24217 | 303003 | 0
24218 | 303003 | 0
24219 | 303003 | 1
24220 | 303003 | 1
24221 | 303003 | 0
24222 | 303003 | 0
I need to group this data like that:
begin_period | end_period| id_account | float_value
24217 | 24218 | 303003 | 0
24219 | 24220 | 303003 | 1
24221 | 24222 | 303003 | 0
I tried row_number by partition and while loop but it didn't work.
I understand this as a gaps-and-isald problem, where you want to group together "adjacent" rows, ie rows having the same float_value
, across records having the same id_account
and parameter
.
Here, I think the simplest approch is to use the difference between row numbers to compute which group each record belongs to:
select
min(period) begin_period,
max(period) end_period,
id_account,
parameter,
float_value
from (
select
t.*,
row_number() over(partition by id_account, parameter order by period) rn1,
row_number() over(partition by id_account, parameter, float_value order by period) rn2
from mytable t
) t
group by id_account, parameter, float_value, rn1 -rn2
order by id_account, parameter, begin_period
begin_period | end_period | id_account | parameter | float_value -----------: | ---------: | ---------: | :------------- | ----------: 24217 | 24218 | 303003 | ACCOUNT_STATUS | 0 24219 | 24220 | 303003 | ACCOUNT_STATUS | 1 24221 | 24222 | 303003 | ACCOUNT_STATUS | 0
This is a gaps and islands problem, and one approach is to use the difference in row numbers method:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ID_Account ORDER BY Period) rn1,
ROW_NUMBER() OVER (PARTITION BY ID_Account, Float_Value ORDER BY Period) rn2
FROM yourTable
)
SELECT
MIN(Period) AS Begin_Period,
MAX(Period) AS End_Period,
ID_Account,
MAX(Parameter) AS Parameter, -- assuming Parameter just always has the same value
Float_Value
FROM cte
GROUP BY
ID_Account,
Float_Value,
rn1 - rn2
ORDER BY
MIN(Period);
You can use row_number
as following. Here is the demo .
with cte as
(
select
*,
rn - row_number() over(order by Float_Value, rn) as nrnk
from
(
select
*,
row_number() over (order by Period) as rn
from Table1
) subq
)
select
min(Period) as Begin_Period,
max(Period) as End_Period,
ID_Account,
Parameter,
Float_Value
from cte
group by
ID_Account,
Parameter,
Float_Value,
nrnk
output:
Begin_Period End_Period ID_Account Parameter Float_Value
---------------------------------------------------------------------
24217 24218 303003 ACCOUNT_STATUS 0
24221 24222 303003 ACCOUNT_STATUS 0
24219 24220 303003 ACCOUNT_STATUS 1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.