I'm curious on the best way to write a query.
I have a table of ids and values. I would like to exclude rows where val is less than val in all of the rows with a lower ID.
I was playing with joining this table to itself on id-1 but that didn't work all of the time.
Some sample data
CREATE TEMP TABLE new_temp_table (
id integer,
val integer
);
INSERT INTO new_temp_table (id, val)
VALUES (0, 300),
(1, 150),
(2, 100),
(3, 200),
(4, 320),
(5, 120),
(6, 220),
(7, 340);
I want the following output.
--- id --- val
--- 0 --- 300
--- 4 --- 320
--- 7 --- 340
Any help/direction would be appreciated.
With NOT EXISTS:
select t.* from new_temp_table t
where not exists (
select 1 from new_temp_table
where id < t.id and val > t.val
)
See the demo .
Results:
| id | val |
| --- | --- |
| 0 | 300 |
| 4 | 320 |
| 7 | 340 |
From what you describe, you can use window functions to calculate the max on all the preceding rows and then filter based on that:
select id, val
from (select ntt.*, max(val) over (order by id rows between unbounded preceding and 1 preceding) as preceding_max
from new_temp_table ntt
) t
where preceding_max is null or val > preceding_max;
Here is a db<>fiddle.
Note: It is tempting to write this logic without the window specification as:
select id, val
from (select ntt.*, max(val) over (order by id) as preceding_max
from new_temp_table ntt
) t
where preceding_max is null or val >= preceding_max;
However, this will return rows where the max equals an earlier maximum.
I would do:
select
id, val, max_prev_val
from (
select
id,
val,
max(val) over(order by id rows between unbounded preceding and 1 preceding)
as max_prev_val
from new_temp_table
) x
where val >= max_prev_val or max_prev_val is null
Result:
id val max_prev_val
----------------------------------------
0 300 <null>
4 320 300
7 340 320
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.