Question

I have a table witrh 3 columns:

id price created_at  
1    0      ts  
2    5      ts  
3    0      ts  
4    3      ts  

I'd like to have a result table that contains 2 rows, like this:

id timestamp  
4  ts  
2  ts

To get the two rows above, I am using two queries.
Here is how I am currently selecting the first row:

select id, to_timestamp(created_at)::timestamp as timestamp
from (select * from web.orders where total > 0) as q 
order by id desc limit 1

Here is how I am selecting the second:

select id, to_timestamp(created_at)::timestamp as timestamp
from (select * from web.orders where total = 0) as q 
order by id desc limit 1

I tried to create the desired result table with UNION ALL of the above queries but it is not working. Any ideas?

Was it helpful?

Solution

If I correctly understood, this should give the desired result:

create table weborders (id int, total int , ts timestamp);
insert into weborders values
(1, 0, '20200101'),
(2, 5, '20200102'),
(3, 0, '20200103'),
(4, 3, '20200104');

with ct as
(
  select   0 as row_no, id, ts
  from     weborders
  where    total > 0
  order by id desc limit 1
)
, ct2 as
(
  select   1 as row_no, id, ts
  from     weborders
  where    total = 0
  order by id desc limit 1
)
select id, ts
from
(
  select row_no, id, ts from ct
  union
  select row_no, id, ts from ct2
) a
order by row_no;

or alternatively:

select id, ts
from
(
 select 0 as row_no, id, ts
 from   weborders
 where id = (select max(id) from weborders where total > 0)
 union
 select 1 as row_no, id, ts
 from   weborders
 where id = (select max(id) from weborders where total = 0)
) a
order by row_no;
id | ts                 
-: | :------------------
 4 | 2020-01-04 00:00:00
 3 | 2020-01-03 00:00:00

db<>fiddle here

And another smart solution, thanks to @ypercubeᵀᴹ for this.

select distinct on (total > 0)
         id, ts
from     weborders
order by (total > 0), id desc ;

db<>fiddle here

OTHER TIPS

do use window functions.

select id, ts, total
from (select
        id, 
        ts, 
        total,  
        rank() over (partition by total = 0 order by id desc) as rnk
      from weborders) as t
where rnk = 1
order by total desc

Dbfiddle

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top