Casting DATE returns "Invalid Month" error - sql

My fiscal year starts on May 1 and ends Apr 30. I am trying to return the fiscal year start date using a CASE statement.
I.e.
CAST(
CASE
WHEN TO_NUMBER (TO_CHAR (GET_DATE, 'MM')) IN (11,
12,
5,
6,
7,
8,
9,
10)
THEN
'05/01/'
|| TO_NUMBER (TO_CHAR (TRUNC (get_date, 'year'), 'YYYY'))
WHEN TO_NUMBER (TO_CHAR (GET_DATE, 'MM')) IN (1,
2,
3,
4)
THEN
'05/01/'
|| TO_NUMBER (TO_CHAR (TRUNC (get_date, 'year'), 'YYYY') - 1)
END AS DATE)
I am getting "invalid month" when I use the cast but when I take it off, it defaults to number. Either way, i'm not getting the results I want.

Just subtract 4 (four) months off your date and pull the year out of it (use trunc to reduce it to the year) then add 4 (four) months back on
SELECT
ADD_MONTHS(
TRUNC(
ADD_MONTHS( <yourdate> ,-4),
'YEAR'),
4)
FROM DUAL;
As to why it works:
We have some example dates: 25-04-2009 13-07-2009
These are in the fiscal years beginning: 01-05-2008 01-05-2009
We subtract 4 months from the date: 25-12-2008 13-03-2009
We trunc down to the year start: 01-01-2008 01-01-2009
We add 4 months back on to get to May: 01-05-2009 01-05-2009
Why is it good/better than converting to string and back? Well, that's the reason right there. Dates are represented as a number, and this method keeps it as a number and works entirely off maths; adding, rounding and substracting. It's always better to avoid unnecessary data type conversions, because thy're slow, resource intensive and can introduce unexpected conversion errors
Using TRUNC with dates is one of the coolest things oracle does with dates that other databases just can't handle. Being able to take any date and TRUNC() it to the start of the year/month/day/hour/minute/weekday etc month is a great help in reports where events are logged to millisecond precision, but you want to summarise or work with them in terms of "number of things that happened this week/month" etc

For Oracle, this get the Start of Fiscal Year for any date.
Just replace "sysdate" function with a variable of type DATE or a column name of type DATE:
select /* for Oracle */
to_date(CASE
WHEN extract(month from sysdate)<5 then
extract(year from sysdate)-1
ELSE
extract(year from sysdate)
end||'-05-01',
'yyyy-mm-dd') as start_fiscal_year
from dual;
Testing on Oracle database using anonymous block:
Declare
/*=========================================================================================
-- objective: calculate Start fiscal date
-- Fisacal year starts on May 1 and ends April 30
--
-- https://stackoverflow.com/questions/52426117/casting-date-returns-invalid-month-error-in-plsql
--
-- Database: Oracle
--
-- 2018-09-20 alvalongo
==========================================================================================*/
dtStart_date date:=to_date('2018-01-10','yyyy-mm-dd');
dtAny_date date;
dtStart_fiscal_date date;
Begin
dbms_output.put_line('I |ANY_DATE |START_FISCAL_YEAR');
for nuI in 0..24 loop
dtAny_date:=add_months(dtStart_date,nuI);
--
select to_date(CASE
WHEN extract(month from dtAny_date)<5 then
extract(year from dtAny_date)-1
ELSE
extract(year from dtAny_date)
end||'-05-01','yyyy-mm-dd') as start_fiscal_year
into dtStart_fiscal_date
from dual;
if extract(month from dtAny_date)=5 then
dbms_output.put_line('--|----------|----------');
end if;
dbms_output.put_line(lpad(nuI,2)
||'|'||to_char(dtAny_date ,'yyyy-mm-dd')
||'|'||to_char(dtStart_fiscal_date,'yyyy-mm-dd')
);
End loop;
End;
/
Output using dbms_output buffer:
I |ANY_DATE |START_FISCAL_YEAR
0|2018-01-10|2017-05-01
1|2018-02-10|2017-05-01
2|2018-03-10|2017-05-01
3|2018-04-10|2017-05-01
--|----------|----------
4|2018-05-10|2018-05-01
5|2018-06-10|2018-05-01
6|2018-07-10|2018-05-01
7|2018-08-10|2018-05-01
8|2018-09-10|2018-05-01
9|2018-10-10|2018-05-01
10|2018-11-10|2018-05-01
11|2018-12-10|2018-05-01
12|2019-01-10|2018-05-01
13|2019-02-10|2018-05-01
14|2019-03-10|2018-05-01
15|2019-04-10|2018-05-01
--|----------|----------
16|2019-05-10|2019-05-01
17|2019-06-10|2019-05-01
18|2019-07-10|2019-05-01
19|2019-08-10|2019-05-01
20|2019-09-10|2019-05-01
21|2019-10-10|2019-05-01
22|2019-11-10|2019-05-01
23|2019-12-10|2019-05-01
24|2020-01-10|2019-05-01
Total execution time 517 ms

Expanding on #CaiusJard's answer, you can get the start of the fiscal year with:
add_months(trunc(add_months(get_date, -4), 'YYYY'), 4)
The add_months(get_date, -4) subtracts four months from the starting date, so a value in January to April will be adjusted to a date in September to December of the previous year. So for instance, 2018-03-11 will become 2017-11-11. But dates dates from May onwards will stay in the same year, so for instance 2018-07-04 becomes 2018-03-04.
Then the trunc(..., 'YYYY') truncates that adjusted value to the first day of its year. So 2018-03-11 becomes 2017-11-11 which becomes 2017-01-01; and 2018-07-04 becomes 2018-03-04 which becomes 2018-01-01.
Then the outer add_months(..., 4) adds four months back on to that adjusted value. So 2018-03-11 becomes 2017-11-11 which becomes 2017-01-01 which finally becomes 2017-05-01; and 2018-07-04 becomes 2018-03-04 which becomes 2018-01-01 which finally becomes 2018-05-01.
To get the last day of the fiscal year you can do the same thing but add an extra 12 months in the final calculation - which gives you the start of the next fiscal year - and then subtract one day:
add_months(trunc(add_months(get_date, -4), 'YYYY'), 16) - 1
Read more about the add_months() and trunc() functions, and about date arithmetic, in the documentation.
Demo with dummy dates in a CTE to show the steps in the adjustment:
with your_table (get_date) as (
select add_months(date '2018-01-15', level)
from dual
connect by level <= 30
)
select get_date,
add_months(get_date, -4) as adjusted_month,
trunc(add_months(get_date, -4), 'YYYY') as adjusted_year,
add_months(trunc(add_months(get_date, -4), 'YYYY'), 4) as start_date,
add_months(trunc(add_months(get_date, -4), 'YYYY'), 16) - 1 as end_date
from your_table
order by get_date;
GET_DATE ADJUSTED_M ADJUSTED_Y START_DATE END_DATE
---------- ---------- ---------- ---------- ----------
2018-02-15 2017-10-15 2017-01-01 2017-05-01 2018-04-30
2018-03-15 2017-11-15 2017-01-01 2017-05-01 2018-04-30
2018-04-15 2017-12-15 2017-01-01 2017-05-01 2018-04-30
2018-05-15 2018-01-15 2018-01-01 2018-05-01 2019-04-30
2018-06-15 2018-02-15 2018-01-01 2018-05-01 2019-04-30
2018-07-15 2018-03-15 2018-01-01 2018-05-01 2019-04-30
...
2019-01-15 2018-09-15 2018-01-01 2018-05-01 2019-04-30
2019-02-15 2018-10-15 2018-01-01 2018-05-01 2019-04-30
2019-03-15 2018-11-15 2018-01-01 2018-05-01 2019-04-30
...
2020-02-15 2019-10-15 2019-01-01 2019-05-01 2020-04-30
2020-03-15 2019-11-15 2019-01-01 2019-05-01 2020-04-30
2020-04-15 2019-12-15 2019-01-01 2019-05-01 2020-04-30
2020-05-15 2020-01-15 2020-01-01 2020-05-01 2021-04-30
2020-06-15 2020-02-15 2020-01-01 2020-05-01 2021-04-30
2020-07-15 2020-03-15 2020-01-01 2020-05-01 2021-04-30
db<>fiddle
As noted elsewhere in comments, your original code is erroring because cast(<string> as date) uses your session's NLS settings, and the string you are constructing does not match that setting. You could use to_date() instead of case so you can supply the expected format mask (see #alvalongo's answer!).

This should be work, if you want to maintain the CASE statement
select CASE WHEN
MONTH(CURRENT_DATE) < 5 THEN
YEAR(CURRENT_DATE)-1 ELSE YEAR(CURRENT_DATE)
end

I tried the following code and it worked for me. DATE is an inbuilt key word so we cannot use that as the column alias. I changed that to FS_START_DATE.
SELECT SYSDATE, TO_DATE(CASE
WHEN TO_NUMBER (TO_CHAR (SYSDATE, 'MM')) IN (11, 12, 5,6,7, 8,9, 10)
THEN '05/01/' || TO_NUMBER (TO_CHAR (TRUNC (SYSDATE, 'year'), 'YYYY'))
WHEN TO_NUMBER (TO_CHAR (SYSDATE, 'MM')) IN (1, 2, 3,4)
THEN '05/01/' || TO_NUMBER (TO_CHAR (TRUNC (SYSDATE, 'year'), 'YYYY') - 1)
END,'MM/DD/YYYY') AS FS_START_DATE FROM DUAL;
I am using TO_DATE function and this returns me 01-MAY-2018.

Related

Oracle get last weekday Mon-Fri

I would like to obtain the last weekday.
If it's Tues to Sat, it will be the previous day. If it's Sunday or Monday, it will be Friday.
So far, I've tried this, but I'm struggling to get the desired output.
SELECT
level AS dow,
trunc(sysdate, 'D') + level day,
to_char(trunc(sysdate, 'D') + level, 'Day') AS day_week,
CASE
WHEN to_char(trunc(sysdate, 'D') + level, 'Day') IN (
'Sunday',
'Monday'
) THEN
trunc(sysdate - 2, 'IW') + 4
ELSE
sysdate - 1
END calculation
FROM
dual
CONNECT BY
level <= 7;
This solution works independent of language and territory:
SELECT date_value,
date_value - CASE TRUNC(date_value) - TRUNC(date_value, 'IW')
WHEN 0 THEN 3 -- Monday
WHEN 6 THEN 2 -- Sunday
ELSE 1 -- Tuesday to Saturday
END AS previous_weekday
FROM table_name;
Which, for the sample data:
CREATE TABLE table_name (date_value) AS
SELECT TRUNC(sysdate - LEVEL + 1)
FROM DUAL
CONNECT BY LEVEL <= 7;
Outputs (with the date format YYYY-MM-DD HH24:MI:SS (DY)):
DATE_VALUE
PREVIOUS_WEEKDAY
2021-07-20 00:00:00 (TUE)
2021-07-19 00:00:00 (MON)
2021-07-19 00:00:00 (MON)
2021-07-16 00:00:00 (FRI)
2021-07-18 00:00:00 (SUN)
2021-07-16 00:00:00 (FRI)
2021-07-17 00:00:00 (SAT)
2021-07-16 00:00:00 (FRI)
2021-07-16 00:00:00 (FRI)
2021-07-15 00:00:00 (THU)
2021-07-15 00:00:00 (THU)
2021-07-14 00:00:00 (WED)
2021-07-14 00:00:00 (WED)
2021-07-13 00:00:00 (TUE)
db<>fiddle here

2020-02-29 minus one year caused error ORA-01839: date not valid for month specified

I have a simple query as:
select to_date('2020-02-29', 'yyyy-mm-dd') - interval '1' year from dual
I think the result should be 2019-02-28, but oracle throws error as:
Error report -
ORA-01839: date not valid for month specified
That is the documented behaviour; it even gives this as an example:
When interval calculations return a datetime value, the result must be
an actual datetime value or the database returns an error. For
example, the next two statements return errors:
SELECT TO_DATE('31-AUG-2004','DD-MON-YYYY') + TO_YMINTERVAL('0-1')
FROM DUAL;
SELECT TO_DATE('29-FEB-2004','DD-MON-YYYY') + TO_YMINTERVAL('1-0')
FROM DUAL;
The first fails because adding one month to a 31-day month would
result in September 31, which is not a valid date. The second fails
because adding one year to a date that exists only every four years is
not valid. However, the next statement succeeds, because adding four
years to a February 29 date is valid:
SELECT TO_DATE('29-FEB-2004', 'DD-MON-YYYY') + TO_YMINTERVAL('4-0')
FROM DUAL;
TO_DATE('
---------
29-FEB-08
The alternative is to use add_months(..., -12) (docs), which won't error:
select add_months(date '2020-02-29', -12) from dual;
ADD_MONTHS
----------
2019-02-28
But note how that deals with different number of days in the month; not really an issue when you're going back exactly a year, but still something to be aware of:
If date is the last day of the month or if the resulting month has fewer days than the day component of date, then the result is the last day of the resulting month.
So some of these might not do what you expected:
with rcte (dt) as (
select last_day(date '2020-01-01')
from dual
union all
select last_day(trunc(dt, 'MM') + interval '1' month)
from rcte
where dt < date '2020-06-01'
)
select dt,
add_months(dt, -12) as minus12, add_months(dt, -3) as minus3, add_months(dt, -1) as minus1,
add_months(dt, 1) as plus1, add_months(dt, 3) as plus3, add_months(dt, 12) as plus12
from rcte
order by dt;
DT MINUS12 MINUS3 MINUS1 PLUS1 PLUS3 PLUS12
---------- ---------- ---------- ---------- ---------- ---------- ----------
2020-01-31 2019-01-31 2019-10-31 2019-12-31 2020-02-29 2020-04-30 2021-01-31
2020-02-29 2019-02-28 2019-11-30 2020-01-31 2020-03-31 2020-05-31 2021-02-28
2020-03-31 2019-03-31 2019-12-31 2020-02-29 2020-04-30 2020-06-30 2021-03-31
2020-04-30 2019-04-30 2020-01-31 2020-03-31 2020-05-31 2020-07-31 2021-04-30
2020-05-31 2019-05-31 2020-02-29 2020-04-30 2020-06-30 2020-08-31 2021-05-31
2020-06-30 2019-06-30 2020-03-31 2020-05-31 2020-07-31 2020-09-30 2021-06-30

Week starting hour gives previous week date instead of current week

In our project we are maintaining a customers weekly spend. For that every week start we are resetting a customer limit.
Whenever customer doing a transaction we are updating his weekly spend by using the below query.
UPDATE SUMMARY
SET WEEKLIMIT = (
SELECT NVL (SUM (AMT / 100), 0)
FROM TRANSACTION
WHERE MOBILENO = :mobileNumber
AND TRUNC(TXNDT) BETWEEN (TRUNC (SYSTIMESTAMP, 'IW') - 1 ) AND TRUNC (SYSTIMESTAMP)
) WHERE MOBILENO = :mobileNumber
But the problem is customer who are doing transaction in sunday 00:00:01 to 01:00:00 hours, the above query updating the previous week limits
instead of current week.
SUMMARY
MOBILENUMBER AMT TXNDATE
0000000000 10000 26-12-2019 09:05:34
0000000000 10000 28-12-2019 11:05:34
0000000000 10000 29-12-2019 00:01:35
When I run this query in sunday first hour it returning
200
But from next hour
it returning only
100
Why the starting hour of week gives the previous week data.
Here is my NLS parameters
NLS_LANGUAGE ENGLISH
NLS_TERRITORY INDIA
NLS_CURRENCY Rs
NLS_ISO_CURRENCY INDIA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MM-RR
NLS_DATE_LANGUAGE ENGLISH
NLS_SORT BINARY
NLS_TIME_FORMAT HH12:MI:SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MM-RR HH12:MI:SSXFF AM
NLS_TIME_TZ_FORMAT HH12:MI:SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MM-RR HH12:MI:SSXFF AM TZR
NLS_DUAL_CURRENCY Rs
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
Any help will be greatly appreciated!!!!
I believe your issue lies in your date manipulation. You are doing:
TRUNC(TXNDT) BETWEEN (TRUNC (SYSTIMESTAMP, 'IW') - 1 ) AND TRUNC (SYSTIMESTAMP)
and expecting that to make the start of the week a Sunday.
However, you haven't done this correctly - your logic says "take the Monday of the current week and subtract a day from it". If your day is a Sunday, that means it first gets the previous Monday and subtracts a day to make it the previous Sunday.
What you must first do is turn the Sunday into a Monday (by adding a day), truncate it to the first day of the week (Monday), and then subtract a day.
Which means your predicate should now look like:
TRUNC(TXNDT) BETWEEN (TRUNC (SYSDATE + 1, 'IW') - 1 ) AND TRUNC (SYSDATE)
Here's a test case demonstrating the difference:
WITH dts AS (SELECT TRUNC(SYSDATE, 'mm') - 1 + LEVEL dt
FROM dual
CONNECT BY LEVEL <= 13)
SELECT dt,
to_char(dt, 'Dy') day_of_week,
TRUNC(dt, 'iw') monday_start_week,
TRUNC(dt, 'iw') - 1 your_sunday_start_week,
TRUNC(dt + 1, 'iw') - 1 actual_sunday_start_week
FROM dts;
DT DAY_OF_WEEK MONDAY_START_WEEK YOUR_SUNDAY_START_WEEK ACTUAL_SUNDAY_START_WEEK
----------- ----------- ----------------- ---------------------- ------------------------
01/01/2020 Wed 30/12/2019 29/12/2019 29/12/2019
02/01/2020 Thu 30/12/2019 29/12/2019 29/12/2019
03/01/2020 Fri 30/12/2019 29/12/2019 29/12/2019
04/01/2020 Sat 30/12/2019 29/12/2019 29/12/2019
05/01/2020 Sun 30/12/2019 29/12/2019 05/01/2020 <-----
06/01/2020 Mon 06/01/2020 05/01/2020 05/01/2020
07/01/2020 Tue 06/01/2020 05/01/2020 05/01/2020
08/01/2020 Wed 06/01/2020 05/01/2020 05/01/2020
09/01/2020 Thu 06/01/2020 05/01/2020 05/01/2020
10/01/2020 Fri 06/01/2020 05/01/2020 05/01/2020
11/01/2020 Sat 06/01/2020 05/01/2020 05/01/2020
12/01/2020 Sun 06/01/2020 05/01/2020 12/01/2020 <-----
13/01/2020 Mon 13/01/2020 12/01/2020 12/01/2020
You can see that for the two Sunday rows, your version returns the previous Sunday, whereas the amended version returns the current Sunday.

How to find first Thursday of a month using Oracle SQL?

How to find First Thursday of this month using oracle?
select trunc(sysdate, 'MM')firstday from dual;
above is getting firstday of this month
Try with the below SQL
SELECT NEXT_DAY(TRUNC(SYSDATE, 'MONTH'),'THURSDAY') FROM DUAL;
SQL Fiddle
If you just get the next Thursday after the first day of the month, the after part means that if the 1st is itself a Thursday you will acually get a date a week too late. For instance, 2018-02-01 was a Thursday, and putting that into next_day() gives you 2018-02-08.
You need to get the next Thursday after the last day of the previous month:
next_day(trunc(sysdate, 'MM') - 1, 'THU')
Demo of both values; look at February, March and November in particular:
with t (dt) as (
select add_months(date '2018-01-15' , level - 1) from dual connect by level <= 12
)
select next_day(trunc(dt, 'MM'), 'THU') as wrong,
next_day(trunc(dt, 'MM') - 1, 'THU') as ok
from t;
WRONG OK
---------- ----------
2018-01-04 2018-01-04
2018-02-08 2018-02-01
2018-03-08 2018-03-01
2018-04-05 2018-04-05
2018-05-03 2018-05-03
2018-06-07 2018-06-07
2018-07-05 2018-07-05
2018-08-02 2018-08-02
2018-09-06 2018-09-06
2018-10-04 2018-10-04
2018-11-08 2018-11-01
2018-12-06 2018-12-06

Calculate week before

I have a table that is populated with info once a week, with the date when it is populated as a single column in the table.
I am working on a query that basically compares data from this week against the data from last week exclusively, therefore I need to know which week was last week. This is easy to accomplish in the following way:
WHERE TO_CHAR(LASTWEEK.DATE_GENERATED, 'IW') = TO_CHAR(SYSDATE, 'IW') -1
AND TO_CHAR(LASTWEEK.DATE_GENERATED, 'YY') = TO_CHAR(SYSDATE, 'YY')
The table may contain data from several years, therefore I also check that the year be the same.
The problem comes when we are in the first week of the year and we want to compare against the previous week. This way we are in week 1 minus 1 it gives us 0, but I want it to compare against week 54 from LAST year.
Is there a way to accomplish this?
I feel that the TRUNC function might work with this but I am unsure as to how to use it in this scenario, also keeping in mind that it should not compare against the same year but last year.
Thanks in advance!
I'd avoid using TO_CHAR in this event altogether ... stay within DATE format ... safer, especially when breaching years ..
where trunc(LASTWEEK.DATE_GENERATED,'IW') = trunc(sysdate-7,'IW')
That single condition should give it to you :)
You can see what it's doing here:
1 with w_data as (select sysdate-level d from dual connect by level <= 20 )
2 select d, trunc(d, 'IW') w
3* from w_data
SQL> /
D W
-------------------- --------------------
09-feb-2016 13:20:41 08-feb-2016 00:00:00
08-feb-2016 13:20:41 08-feb-2016 00:00:00
07-feb-2016 13:20:41 01-feb-2016 00:00:00
06-feb-2016 13:20:41 01-feb-2016 00:00:00
05-feb-2016 13:20:41 01-feb-2016 00:00:00
04-feb-2016 13:20:41 01-feb-2016 00:00:00
03-feb-2016 13:20:41 01-feb-2016 00:00:00
02-feb-2016 13:20:41 01-feb-2016 00:00:00
01-feb-2016 13:20:41 01-feb-2016 00:00:00
31-jan-2016 13:20:41 25-jan-2016 00:00:00
30-jan-2016 13:20:41 25-jan-2016 00:00:00
29-jan-2016 13:20:41 25-jan-2016 00:00:00
28-jan-2016 13:20:41 25-jan-2016 00:00:00
27-jan-2016 13:20:41 25-jan-2016 00:00:00
26-jan-2016 13:20:41 25-jan-2016 00:00:00
25-jan-2016 13:20:41 25-jan-2016 00:00:00
24-jan-2016 13:20:41 18-jan-2016 00:00:00
23-jan-2016 13:20:41 18-jan-2016 00:00:00
22-jan-2016 13:20:41 18-jan-2016 00:00:00
21-jan-2016 13:20:41 18-jan-2016 00:00:00
20 rows selected.
You can compare with a date a week ago, by using sysdate - 7, and combine with a single value:
WHERE TO_CHAR(LASTWEEK.DATE_GENERATED, 'IYYYIW') = TO_CHAR(SYSDATE - 7, 'IYYYIW')
Notice I'm using the IYYY year model to match the IW one, otherwise you'd get odd results.
But as #ditto shows it's cleaner to use TRUNC with the IW format mask. And as #MaxU pointed out truncating the source column will prevent indexes being used, unless you have a matching function-based index. You can avoid that by modifying Ditto's approach slightly:
WHERE LASTWEEK.DATE_GENERATED >= TRUNC(SYSDATE - 7, 'IW')
AND LASTWEEK.DATE_GENERATED < TRUNC(SYSDATE, 'IW');
As a demo:
with lastweek(date_generated) as (
select sysdate - level from dual connect by level <= 50
)
SELECT LASTWEEK.DATE_GENERATED
FROM LASTWEEK
WHERE LASTWEEK.DATE_GENERATED >= TRUNC(SYSDATE - 7, 'IW')
AND LASTWEEK.DATE_GENERATED < TRUNC(SYSDATE, 'IW');
DATE_GENERATED
--------------
2016-02-07
2016-02-06
2016-02-05
2016-02-04
2016-02-03
2016-02-02
2016-02-01
Or to see the year change, lets go back further, again just as a demo:
with lastweek(date_generated) as (
select sysdate - level from dual connect by level <= 50
)
SELECT LASTWEEK.DATE_GENERATED
FROM LASTWEEK
WHERE LASTWEEK.DATE_GENERATED >= TRUNC(SYSDATE - 42, 'IW')
AND LASTWEEK.DATE_GENERATED < TRUNC(SYSDATE - 35, 'IW');
DATE_GENERATED
--------------
2016-01-03
2016-01-02
2016-01-01
2015-12-31
2015-12-30
2015-12-29
2015-12-28
the query from Ditto will work, but it will not use indexes on "LASTWEEK.DATE_GENERATED" column, because of applied function (trunc), so i would go for the following:
select
next_day(to_date('2016-01-10','yyyy-mm-dd')-14, 'MONDAY'),
next_day(to_date('2016-01-10','yyyy-mm-dd')-14, 'SUNDAY')
from dual;
Output:
12/28/2015 01/03/2016
So your query would be:
WHERE LASTWEEK.DATE_GENERATED
between next_day(to_date('2016-01-10','yyyy-mm-dd')-14, 'MONDAY')
and next_day(to_date('2016-01-10','yyyy-mm-dd')-14, 'SUNDAY')