Oracle Sysdate > NULL - sql

I am looking into a scenario some similar to future dated stuff.
I have a table something similar to this
ProductID ProductStatus EffectiveFromDate EffectiveToDate CancelledIndicator
----------- ------------- ----------------- --------------- ------------------
345 A 7/7/2016 (null) 1
345 S 7/7/2016 11/7/2016 (null)
345 A 12/7/2016 (null) (null)
I need to fetch the current dated product
if I find a cancelled indicator it means it is no more active
if their are two rows one with future dated status.
Based on the table above I get a latest record if I check for the efd < sysdate and etd is null. but to get the current active status which is the case which i need to implement.
I need to check if the sysdate is b/w the efd and etd of the older record if not I need to take the latest record which will be the current status.
I have query which does that
but the thing is what happens when I check
sysdate between efd and etd where etd can be null most of the time.

Some samples of how you can handle it:
setup:
SQL> create table testNull (id, startDate, endDate) as
2 (
3 select 1, null, sysdate + 1 from dual union all
4 select 2, sysdate -1, sysdate + 1 from dual union all
5 select 3, sysdate -1, null from dual union all
6 select 4, sysdate -3, sysdate - 1 from dual
7 );
Table created.
without handling NULL:
SQL> select *
2 from testNull
3 where sysdate between startDate and endDate ;
ID STARTDATE ENDDATE
---------- --------- ---------
2 11-LUG-16 13-LUG-16
with COALESCE:
SQL> select *
2 from testNull
3 where sysdate between startDate and coalesce(endDate, sysdate);
ID STARTDATE ENDDATE
---------- --------- ---------
2 11-LUG-16 13-LUG-16
3 11-LUG-16
with some boolean logic:
SQL> select *
2 from testNull
3 where sysdate >= startDate
4 and ( endDate is null or sysdate <= endDate);
ID STARTDATE ENDDATE
---------- --------- ---------
2 11-LUG-16 13-LUG-16
3 11-LUG-16

Related

Oracle sql: if I am doing a comparison operator on a date field do i still need a not null

If I am doing a comparison operator (>, <, =) on a date field do I also need a IS NOT NULL on the date field
If I understood you correctly, then no - you don't have to check whether it is not null.
For example (today is date '2022-07-07', 7th of July 2022):
SQL> with test (id, date_column) as
2 (select 1, date '2022-05-25' from dual union all -- before today
3 select 2, date '2022-12-13' from dual union all -- after today
4 select 3, null from dual -- unknown, as there's no value in DATE_COLUMN
5 )
6 select *
7 from test
8 where date_column >= sysdate;
ID DATE_COLUM
---------- ----------
2 2022-12-13
SQL>
If you include the not null check, you'll get the same result:
<snip>
6 select *
7 from test
8 where date_column is not null
9 and date_column >= sysdate;
ID DATE_COLUM
---------- ----------
2 2022-12-13
SQL>

PLSQL How to split each row based on begin and end date

Could you please assist me to split each row and create multiple rows for each date between begin_date and end_date.
ID CODE VIEW BEGIN_DATE END_DATE
-------------------------------------------
10400 null 2 17-FEB-20 17-FEB-20
10650 null 2 17-FEB-20 18-FEB-20
10900 null 2 19-FEB-20 21-FEB-20
10901 null 2 21-FEB-20 02-MAR-20
11650 2723 2 02-MAR-20 04-MAR-20
11650 1002 2 02-MAR-20 04-MAR-20
11650 1001 2 02-MAR-20 04-MAR-20
11650 1000 2 02-MAR-20 04-MAR-20
Currently I'm using below query but it doesn't seem to work
select
r.*
from rec r
connect by level <= end_date - begin_date + 1;
what i want is to some thing like this
ID CODE VIEW DATE
----------------------------------
11650 2723 2 02-MAR-20
11650 2723 2 03-MAR-20
11650 2723 2 04-MAR-20
.... continue
Here's one option:
Sample data:
SQL> with test (id, code, cview, begin_date, end_date) as
2 (select 10400, null, 2, date '2020-02-17', date '2020-02-17' from dual union all
3 select 10650, null, 2, date '2020-02-17', date '2020-02-18' from dual union all
4 select 11650, 2723, 2, date '2020-03-02', date '2020-03-04' from dual
5 )
Query begins here:
6 select id,
7 code,
8 cview,
9 begin_date + column_value - 1 as datum
10 from test cross join
11 table(cast(multiset(select level from dual
12 connect by level <= end_date - begin_date + 1
13 ) as sys.odcinumberlist))
14 order by id, datum;
ID CODE CVIEW DATUM
---------- ---------- ---------- ----------
10400 2 17.02.2020
10650 2 17.02.2020
10650 2 18.02.2020
11650 2723 2 02.03.2020
11650 2723 2 03.03.2020
11650 2723 2 04.03.2020
6 rows selected.
SQL>

How do I subtract multiple dates?

An image of the Discharge date and admission date in which i am supposed to subtract as (discharge date – admitted
date) +1 .
As you said - subtract and sum. Sample data in lines #1 - 5, query begins at line #6.
SQL> with test (who, admission_date, discharge_date) as
2 (select 'Leslie', date '2010-09-13', date '2010-09-25' from dual union all
3 select 'Leslie', date '2014-09-03', date '2014-09-21' from dual union all
4 select 'Leslie', date '2015-12-03', date '2015-12-14' from dual
5 )
6 select who, sum(discharge_date - admission_date + 1) total_days
7 from test
8 group by who;
WHO TOTAL_DAYS
------ ----------
Leslie 44
SQL>

How to List Specification Data

I wrote a view. Example of view you can see under the code.
I am writing a script for the list data.
Example of view:
DONEM_ID, URUN_ID, TARIFF, TARIFE_PRI, START_DATE, END_DATE
xx10 1 12 123 01-02-2003 null
xx11 1 12 123 01-02-2003 01-11-2003
xx12 1 12 124 01-11-2003 null
I wanna list
URUN_ID, TARIFF, TARIFE_PRI, START_DATE, END_DATE
1 12 123 01-02-2003 01-11-2003
1 12 124 01-11-2003 null
How can i list this?
Aggregation usually helps (code you might need begins at line #8):
SQL> alter session set nls_date_format = 'mm-dd-yyyy';
Session altered.
SQL> with
2 -- sample data; you have that, don't type it
3 test (donem_id, urun_id, tariff, tarife_pri, start_date, end_date) as
4 (select 'xx10', 1, 12, 123, date '2003-01-02', null from dual union all
5 select 'xx11', 1, 12, 123, date '2003-01-02', date '2003-01-11' from dual union all
6 select 'xx12', 1, 12, 124, date '2003-01-11', null from dual
7 )
8 select urun_id, tariff, tarife_pri, min(start_date) start_date, max(end_date) end_date
9 from test
10 group by urun_id, tariff, tarife_pri
11 order by urun_id, tariff, tarife_pri;
URUN_ID TARIFF TARIFE_PRI START_DATE END_DATE
---------- ---------- ---------- ---------- ----------
1 12 123 01-02-2003 01-11-2003
1 12 124 01-11-2003
SQL>

Select query that creates a table of monthly incremental entries

I need to be able to use a select query that will somehow generate a list of entries consisting of monthly increments from two variables STARTDATE and ENDDATE. An example would look like this:
Getting the STARTDATE and ENDDATE from the table
STARTDATE ENDDATE
----------- -----------
01-JAN-2011 1-DEC-2011
which results into
CALENDAR
---------
01-JAN-11
01-FEB-11
01-MAR-11
01-APR-11
01-MAY-11
01-JUN-11
01-JUL-11
01-AUG-11
01-SEP-11
01-OCT-11
01-NOV-11
01-DEC-11
Any ideas on how to doing this? Someone told me about a method called 'CONNECT BY' but it doesn't work with leap year or something.
Thanks.
Something like this should work
SQL> ed
Wrote file afiedt.buf
1 with x as (
2 select date '2011-01-01' start_date,
3 date '2011-12-01' end_date
4 from dual
5 )
6 select add_months( start_date, level-1 )
7 from x
8* connect by level <= months_between( end_date, start_date ) + 1
SQL> /
ADD_MONTH
---------
01-JAN-11
01-FEB-11
01-MAR-11
01-APR-11
01-MAY-11
01-JUN-11
01-JUL-11
01-AUG-11
01-SEP-11
01-OCT-11
01-NOV-11
01-DEC-11
12 rows selected.