You can combine into a single query and a single pass over the table using analytic functions, generating two pseudocolumns in this case:
select column1, column2, column3,
row_number() over (order by column1 desc) rn_desc,
row_number() over (order by column1 asc) rn_asc
from your_table;
and then filtering using that query as an inline view (or CTE):
select column1, column2, column3
from (
select column1, column2, column3,
row_number() over (order by column1 desc) as rn_desc,
row_number() over (order by column1 asc) as rn_asc
from your_table
)
where rn_desc <=5
or rn_asc <= 5;
I've assumed your ordering is on column1
, and picked your_table
as a table name as you didn't include that either, so change as appropriate. Depending on how you want to handle ties, you might want to use the rank()
or dense_rank()
functions instead.
From @mathguy's comment, this may well perform better:
select column1, column2, column3
from (
select column1, column2, column3,
row_number() over (order by column1 desc) as rn,
count(*) over () as cnt
from your_table
)
where rn <=5
or cnt - rn < 5;