Let’s say I have the following data set:
ID | Identifier | Admission_Date | Release_Date |
---|---|---|---|
234 | 2 | 5/1/22 | 5/5/22 |
234 | 1 | 4/25/22 | 4/30/22 |
234 | 2 | 4/20/22 | 4/24/22 |
234 | 2 | 4/15/22 | 4/18/22 |
789 | 1 | 7/15/22 | 7/19/22 |
789 | 2 | 7/8/22 | 7/14/22 |
789 | 2 | 7/1/22 | 7/5/22 |
321 | 2 | 6/1/21 | 6/3/21 |
321 | 2 | 5/27/21 | 5/31/21 |
321 | 1 | 5/20/21 | 5/26/21 |
321 | 2 | 5/15/21 | 5/19/21 |
321 | 2 | 5/6/21 | 5/10/21 |
I want all rows with identifier=1
. I also want rows that are either directly below or above rows with Identifier=1
– sorted by most recent to least recent.
There is always a row below rows with identifier=1
. There may or may not be a row above. If there is no row with identifier=1
for an ID
, then it will not be brought in with a prior step.
The resulting data set should be as follows:
ID | Identifier | Admission Date | Release Date |
---|---|---|---|
234 | 2 | 5/1/22 | 5/5/22 |
234 | 1 | 4/25/22 | 4/30/22 |
234 | 2 | 4/20/22 | 4/24/22 |
789 | 1 | 7/15/22 | 7/19/22 |
789 | 2 | 7/8/22 | 7/14/22 |
321 | 2 | 5/27/21 | 5/31/21 |
321 | 1 | 5/20/21 | 5/26/21 |
321 | 2 | 5/15/21 | 5/19/21 |
I am using DBeaver, which runs PostgreSQL.
2
Answers
I admittedly don’t know Postgres well so the following could possibly be optimised, however using a combination of lag and lead to obtain the previous and next dates (assuming Admission_date is the one to order by) you could try
One way:
db<>fiddle here
The query is designed to only make a single pass over the table.
Uses some advanced SQL / Postgres features.
About
LATERAL
:About the
VALUES
expression:The manual about extracting fields from a composite type.
If there are many rows per
id
, other solutions will be (much) faster – with proper index support. You did not specify …