Reputation: 137
I hae a flag and date combination in my table, so my table is like this
DATE FLAG
----------------
01-JAN-18 1
02-JAN-18 0.5
03-JAN-18 3
06-JAN-18 9
I want an SQL query for this table which returns me 0 or 1 for a particular date based on weather the previous maximum date in table was with flag 0 or not
I have tried this- first I get previous day for a particular day-
max_date = select max(date) from table where date < input_date;
after getting this date I get the flag for this date
select flag from table where date=max_date
I want a smart/better way to do this
Upvotes: 0
Views: 57
Reputation: 31726
LAG
is a good option, but if you wish to not use any analytical functions, you may have to use multiple joins.
You want a case where the previous flag value is zero, but you don't bother to give one example or expected output in your question. I have added it anyway.
Oracle 11g R2 Schema Setup:
create table yourtable as
select TO_DATE ('01-JAN-2018','DD-MON-YYYY') dt, 1 flag from dual UNION ALL
select TO_DATE ('02-JAN-2018','DD-MON-YYYY'), 0.5 from dual UNION ALL
select TO_DATE ('03-JAN-2018','DD-MON-YYYY'), 3 from dual UNION ALL
select TO_DATE ('06-JAN-2018','DD-MON-YYYY'), 9 from dual UNION ALL
select TO_DATE ('08-JAN-2018','DD-MON-YYYY'), 0 from dual UNION ALL
select TO_DATE ('11-JAN-2018','DD-MON-YYYY'), 7 from dual UNION ALL
select TO_DATE ('14-JAN-2018','DD-MON-YYYY'), 12 from dual
Query 1:
SELECT s.dt,s.flag,
CASE
WHEN t.flag = 0 THEN 1
ELSE 0
END is_prev_dt_flag_zero
FROM yourtable t
RIGHT OUTER JOIN (SELECT a.dt,MAX(a.flag) flag,
Max(b.dt) prev_date
FROM yourtable a
LEFT OUTER JOIN yourtable b
ON b.dt < a.dt
GROUP BY a.dt) s
ON t.dt = s.prev_date
ORDER BY s.dt
| DT | FLAG | IS_PREV_DT_FLAG_ZERO |
|----------------------|------|----------------------|
| 2018-01-01T00:00:00Z | 1 | 0 |
| 2018-01-02T00:00:00Z | 0.5 | 0 |
| 2018-01-03T00:00:00Z | 3 | 0 |
| 2018-01-06T00:00:00Z | 9 | 0 |
| 2018-01-08T00:00:00Z | 0 | 0 |
| 2018-01-11T00:00:00Z | 7 | 1 |
| 2018-01-14T00:00:00Z | 12 | 0 |
Upvotes: 0
Reputation: 49270
Use lag
with a case
expression.
select dt,flag,case when lag(flag) over(order by dt) = 0 then 1 else 0 end as prev_zero_or_not
from tbl
Upvotes: 1