Reputation: 149
I have a table which has the below sample for only one line_id.
LINE_ID|COLLECTION_DATE |DSL_CARD_TYPE|
-------|-------------------|-------------|
1234567|2020-03-25 08:46:08|ADSL_PORT |
1234567|2020-03-26 08:31:48|ADSL_PORT |
1234567|2020-03-27 08:42:40|VDSL_PORT |
1234567|2020-03-28 08:36:32|VDSL_PORT |
1234567|2020-03-29 08:31:33|VDSL_PORT |
1234567|2020-03-30 08:50:15|VDSL_PORT |
1234567|2020-04-31 08:44:33|ADSL_PORT |
1234567|2020-03-01 08:34:53|ADSL_PORT |
1234567|2020-04-02 08:44:11|ADSL_PORT |
1234567|2020-04-03 08:43:51|VDSL_PORT |
1234567|2020-04-04 08:54:33|ADSL_PORT |
1234567|2020-04-05 09:06:47|ADSL_PORT |
1234567|2020-04-06 09:06:57|VDSL_PORT |
1234567|2020-04-07 09:13:32|VDSL_PORT |
What I need is to group DSL_CARD_TYPE and create a new column called Next_COLLECTION_DATE to get the next DSL_CARD_TYPE and return the first date in each Next_group but like below
LINE_ID|COLLECTION_DATE |Next_COLLECTION_DATE |DSL_CARD_TYPE|
-------|-------------------|----------------------|-------------|
1234567|2020-03-25 08:46:08|2020-03-27 08:42:40 |ADSL_PORT |
1234567|2020-03-27 08:42:40|2020-03-31 08:34:53 |VDSL_PORT |
1234567|2020-03-31 08:34:53|2020-04-03 08:43:51 |ADSL_PORT |
1234567|2020-04-03 08:43:51|2020-04-04 08:54:33 |VDSL_PORT |
1234567|2020-04-04 08:54:33|2020-04-06 09:06:57 |ADSL_PORT |
1234567|2020-04-06 09:06:57|2020-04-07 09:13:32 |VDSL_PORT |
I have the below code and it returns the last date in each group
select line_id, dsl_card_type, min(collection_date), max(collection_date)
from (select v.*,
row_number() over (partition by line_id order by collection_date) as seqnum,
row_number() over (partition by line_id, dsl_card_type order by collection_date) as seqnum_2
from ANALYTICS.tmp.V_PORTS_LINE_CARD_DATA_ALL v
where collection_date >= '2020-07-27 00:00:00'
) v
group by line_id, dsl_card_type, (seqnum - seqnum_2);```
Upvotes: 2
Views: 769
Reputation: 1270463
You can do this using lead()
and lag()
:
select line_id, dsl_card_type, collection_date,
lead(collection_date) over (partition by line_id order by collection_date)
from (select v.*,
lag(dsl_card_type) over (partition by line_id order by collection_date) as prev_dsl_card_type
from ANALYTICS.tmp.V_PORTS_LINE_CARD_DATA_ALL v
where collection_date >= '2020-07-27 00:00:00'
) v
where prev_dsl_card_type is null or prev_dsl_card_type <> dsl_card_type;
Voila! No aggregation is needed.
Upvotes: 1
Reputation: 222582
You can use lead()
in the outer query:
select
line_id,
dsl_card_type,
min(collection_date) as first_collection_date,
lead(min(collection_date)) over(partition by line_id order by min(collection_date)) next_collection_date
from (select v.*,
row_number() over (partition by line_id order by collection_date) as seqnum,
row_number() over (partition by line_id, dsl_card_type order by collection_date) as seqnum_2
from ANALYTICS.tmp.V_PORTS_LINE_CARD_DATA_ALL v
where collection_date >= '2020-07-27 00:00:00'
) v
group by line_id, dsl_card_type, (seqnum - seqnum_2)
Upvotes: 1