Is this what you are looking for?
WHERE to_char(date, 'YYYY-IW') BETWEEN to_char(sysdate - 21, 'YYYY-IW') AND
to_char(sysdate, 'YYYY-IW')
Question
I'm looking to create a query in Oracle (Web Intelligence to be specific) that selects records based on the current week number. I'm using the ISO standard so the format is "IW". I understand this is an unusual request (to query based on week#. compared to returning as a week #
format), however I'm working in Public Health and it is a common practice to query data based on the current epidemiological week. In this instance, I am substituting the epi week for the ISO standard.
In pseudo code it would look like this:
SELECT * FROM * WHERE date BETWEEN *WEEK#ONE* AND *CURRENTWEEK#*
WEEK#ONE
would be a digit between 1-52 that is 3 less than CURRENTWEEK#
, which is the current ISO week number.
So far I have started dabbling in to_date('01', 'IW')
as an example, but I just keep hitting road blocks. Any help would be really appreciated :)
Solution 2
Is this what you are looking for?
WHERE to_char(date, 'YYYY-IW') BETWEEN to_char(sysdate - 21, 'YYYY-IW') AND
to_char(sysdate, 'YYYY-IW')
OTHER TIPS
You can create a function to convert a year and an ISO week number to a date:
CREATE FUNCTION TO_ISO_WEEK_DATE(
week NUMBER,
year NUMBER
) RETURN DATE DETERMINISTIC
IS
BEGIN
RETURN NEXT_DAY(
TO_DATE( year || '0104', 'YYYYMMDD' )
- INTERVAL '7' DAY, 'MONDAY'
)
+ ( week - 1 ) * 7;
END TO_ISO_WEEK_DATE;
/
Query 1:
SELECT LEVEL AS week,
TO_ISO_WEEK_DATE( LEVEL, 2013 ) AS "date",
TO_CHAR( TO_ISO_WEEK_DATE( LEVEL, 2013 ), 'IW' ) AS "Check"
FROM DUAL
CONNECT BY LEVEL <= 5
| WEEK | DATE | CHECK |
|------|---------------------------------|-------|
| 1 | December, 31 2012 00:00:00+0000 | 01 |
| 2 | January, 07 2013 00:00:00+0000 | 02 |
| 3 | January, 14 2013 00:00:00+0000 | 03 |
| 4 | January, 21 2013 00:00:00+0000 | 04 |
| 5 | January, 28 2013 00:00:00+0000 | 05 |
You can then use this function to determine which dates you are searching between:
SELECT *
FROM tbl
WHERE "date" BETWEEN TO_ISO_WEEK_DATE( :currentweek - 3, 2014 )
AND TO_ISO_WEEK_DATE( :currentweek, 2014 );
If you want to do it without the function then you can unwrap the code within the function:
SELECT *
FROM tbl
WHERE "date" BETWEEN NEXT_DAY( TO_DATE( :currentyear || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY' ) + ( :currentweek - 4 ) * 7
AND NEXT_DAY( TO_DATE( :currentyear || '0104', 'YYYYMMDD' ) - INTERVAL '7' DAY, 'MONDAY' ) + ( :currentweek - 1 ) * 7;