Reputation: 797
I have the following data structure
Date1 | Date2 | a | b
2018-11-15 | 2010-11-15 | 1 | null
2018-11-15 | 2011-11-15 | 0 | 300
2018-11-15 | 2012-11-15 | 0 | 100
2018-11-14 | 2010-11-15 | 1 | 200
2018-11-14 | 2012-11-15 | 0 | 100
2018-11-13 | 2010-11-15 | 1 | null
2018-11-13 | 2011-11-15 | 0 | 100
For each unique Date1 I need to
select row with a = 1 (there is only 1 of such row) if b is not null
otherwise find a row with Date2 being maximum (doesn't matter b is null or not).
So ideally I would like to get
Date1 | Date2 | a | b
2018-11-15 | 2012-11-15 | 0 | 100
2018-11-14 | 2010-11-15 | 1 | 200
2018-11-13 | 2011-11-15 | 0 | 100
I assume I need to combine Group BY Date1 and CASE THEN conditions but could figure out how that should work. Appreciate any hint.
Upvotes: 0
Views: 709
Reputation: 164099
You can do it with UNION ALL and NOT EXISTS:
select * from tablename
where a = 1 and b is not null
union all
select t.* from tablename t
where
not exists (
select 1 from tablename
where date1 = t.date1 and (date2 > t.date2 or (a = 1 and b is not null))
)
See the demo.
Results:
| Date1 | Date2 | a | b |
| ------------------- | ------------------- | --- | --- |
| 2018-11-15 00:00:00 | 2012-11-15 00:00:00 | 0 | 100 |
| 2018-11-14 00:00:00 | 2010-11-15 00:00:00 | 1 | 200 |
| 2018-11-13 00:00:00 | 2011-11-15 00:00:00 | 0 | 100 |
Upvotes: 1
Reputation: 222482
You can use row_number()
with conditional ordering:
select date1, date2, a, b
from (
select
t.*,
row_number() over(
partition by date1
order by
case when a = 1 and b is not null then 0 else 1 end,
date2 desc,
b desc
) rn
from mytable t
) t
where rn = 1
It is quite unclear whether you want to partition by just date1
or date1
and date2
. Since you said you want the record with max date2
, I assumed that you want partitions of date1
and a sorting criteria on date2 desc
.
Finally, I added a third sorting criteria b desc
to try and make the results (more) predictable if there are ties in the first two criterias.
Upvotes: 1