In oracle SQL, how would you obtain the timestamp representing the start of the week? - sql

I'm using an Oracle 9i database and want to obtain, within a function, the timestamp representing the start of the week, i.e. The most recent monday, at 00:00:00.
I am aware that the timestamp representing the start of the current day is TO_TIMESTAMP(SYSDATE).

You can use the function next_day to get that:
SQL> select next_day(sysdate-7, 'MONDAY') FROM DUAL;
NEXT_DAY
---------
29-APR-13

Getting the start of the week should work with trunc (see docs).
So,
select to_timestamp(trunc(sysdate, 'D')) from dual
should work.
However, depending on your NLS settings, the first day of the week for oracle may well be Sunday.

this appears to return Monday before the day of week in question at midnight. to prove out just play around with sysdate and subtract days...
select case when to_Char(sysdate,'d') = 1 then
trunc(sysdate-6)
else
trunc(sysdate - (to_Char(sysdate,'d')-2))
END
from dual;

You can truncate a date to Monday with:
select trunc(sysdate, 'IW') FROM DUAL;

Related

Identify the day and get the previous date in Oracle SQL

I have below query which gives current date. I want to return the value as String for this reason i used TO_CHAR.
select NVL(TO_CHAR(sysdate,'DD.MM.YYYY'),0) from dual
But i need to identify Day and based on this it should return the previous Date.
For example when the query runs on every Monday it should return the date from last Friday. When the query runs from Tuesday till Friday it should return the date from previous day.
For example when the query runs today it should return the date from last Friday i.e 18.02.2022. When the query runs tommorow it should return the date from Today 21.02.2022.
I want to avoid dates from every Saturday and Sunday. Can we do this in one query ?
If you want to do it so that the query will work in any language and/or territory then you can compare the date to the start of the ISO week:
SELECT TO_CHAR(SYSDATE, 'DD.MM.YYYY') AS today,
CASE TRUNC(SYSDATE) - TRUNC(SYSDATE, 'IW')
WHEN 0 THEN TO_CHAR(SYSDATE - 3, 'DD.MM.YYYY') -- Monday
WHEN 6 THEN TO_CHAR(SYSDATE - 2, 'DD.MM.YYYY') -- Sunday
ELSE TO_CHAR(SYSDATE - 1, 'DD.MM.YYYY') -- Any other day
END AS previous_weekday
FROM DUAL;
db<>fiddle here
As a slight variation on MTO's answer, just to perhaps make it clearer to a future maintainer, you could use day names or abbreviations instead - but would need to specify the date language (which maybe assumes the hypothetical future maintainer uses, or at least understands, that language):
select to_char(sysdate
- case to_char(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH')
when 'MON' then 3
when 'SUN' then 2
else 1
end, 'DD.MM.YYYY') as result
from dual
RESULT
----------
18.02.2022
db<>fiddle, including what you see for a range of 14 days, not just today.

Oracle : Query to get the Last Friday of the week if I give any date

If I give a date let's say '13-Mar-2019' my query needs to retrieve the value '15-Mar-2019'. Which is the last Friday of the week.
Trancate the date to the ISO week, which gets you the week's Monday (as an ISO week starts with Monday). Then add four days:
select trunc(date '2019-03-13', 'iw') + 4 from dual;
I would use next_day(). It is the Oracle function specifically designed for this purpose.
select next_day(date '2019-03-13', 'Fri')
from dual;
The only nuance is that if the date is Friday, then it will return the next Friday. That might be what you want. Otherwise, just subtract one day:
select next_day(date '2019-03-13' - 1, 'Fri') as friday_end_of_week
from dual;
Try below -
select trunc(to_date('13-Mar-2019'), 'iw') + 4 from dual
SELECT NEXT_DAY( to_date('2019-03-13', 'yyyy-mm-dd'), to_char(to_date('2019-03-01', 'yyyy-mm-dd'), 'DAY')) FROM dual;
demo

DB2 to Oracle Conversion For Basic Date Time Column Between Clause

What this is doing is selecting all columns from TABLE where a specific date time column is between last Sunday and this coming Saturday, 7 days total (no matter what day of the week you are running the query on)
I would like to have help converting the below statement into Oracle since I found out that it will not work on Oracle.
SELECT *
FROM TABLE
WHERE DATE_TIME_COLUMN
BETWEEN
current date - ((dayofweek(current date))-1) DAYS
AND
current date + (7-(dayofweek(current date))) DAYS
After poking around a bit more I was able to find something that worked for my specific problem with no administrator restrictions for whatever reason:
SELECT *
FROM TABLE
WHERE DATE_TIME_COLUMN
BETWEEN
TIMESTAMPADD(SQL_TSI_DAY, DayOfWeek(Current_Date)*(-1) + 1, Current_Date)
AND
TIMESTAMPADD(SQL_TSI_DAY, 7 - DayOfWeek(Current_Date), Current_Date)
Use TRUNC() to truncate to the start of the week:
SELECT *
FROM TABLE
WHERE DATE_TIME_COLUMN
BETWEEN trunc(sysdate, 'WW')
and
trunc(sysdate + 7, 'WW');
sysdate is the current system date, trunc truncates a data, and WW tells it to truncate to the week (rather than day, year, etc.).
Assuming DATE_TIME_COLUMN is - as it should be - of datatype date, I think this gets what you want.
where DATE_TIME_COLUMN between
next_day(sysdate,'SUNDAY')-7 and next_day(sysdate,'SATURDAY')
You may need to tweak it a bit. Please follow up studying the official docs on the NEXT_DAY function in the relevant docs at http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions106.htm#SQLRF00672
The proposed TRUNC does not guarantee you get the date of a particular day of the week:
SQL> alter session set nls_date_format='day dd-mon-yyyy';
Session altered.
SQL> select trunc(sysdate,'WW') from dual;
TRUNC(SYSDATE,'WW')
---------------------
friday 22-jan-2016
SQL> select trunc(sysdate+7,'WW') from dual;
TRUNC(SYSDATE+7,'WW')
---------------------
friday 29-jan-2016

In Oracle SQL, how to get the time for only this current week?

I have a query , where I want to obtain some data for different time durations (this month, this week, etc).
For the "this week" column, I want it to get all the data from the most recent Monday until now. How would I do this?
I have the following SQL so far :
WHERE prla.CREATION_DATE >= SYSDATE - ?
trunc(sysdate, 'iw') is what you're after. IW is the format mask used for Monday of the week the specified date is in (as Monday is the ISO standard for the start of the week). E.g.:
with dates as (select trunc(sysdate, 'mm') - 10 + level dt
from dual
connect by level <= 40)
select dt
from dates
where dt >= trunc(sysdate, 'iw')
and dt <= sysdate; -- only needed if the dates in the column could be beyond now.
Yeah that will do: But it is better to use sysdate-8. Because if the current day is same as your searching day, it will return the current date. For Eg.
select next_day(sysdate-7,'WED') from dual;
OUTPUT
19-AUG-15
Whereas the below one will give you the last week
select next_day(sysdate-8,'WED') from dual;
OUTPUT
12-AUG-15
You should truncate the current date.
TRUNC(SYSDATE, 'DAY')
This should give you the first day of the week, which is Monday in lot of countries.
If it's giving you the previous Sunday instead you should do this.
TRUNC(SYSDATE, 'DAY')+1
I found out to do this now:
select next_day (sysdate-7, 'MONDAY') Last_Monday from dual;
So in my case, we can remove the SYSDATE subtraction and it is simply :
prla.CREATION_DATE >= next_day (sysdate-7, 'MONDAY')
source

trunc / sysdate... funny syntax need explanation

I believe this outputs the date of Sunday of the current week but I don't know why.
Can someone please break down what's going on here.
SELECT trunc(sysdate+1,'DAY') FROM DUAL;
The TRUNC function will return the starting day of the week when the second parameter is DAY. Today Sysdate returns Thursday, +1 returns Friday etc. So when you add 3 it gives you next Sunday which marks the start of a new week.
Run this to understand what trunc does
SELECT to_char(trunc(sysdate+1, 'DAY'),'dd/mon/yyyy hh:mi:ss') FROM DUAL;
DAY does returns starting day of the week but trunc will also cut off the hours, minutes, seconds of that date. Sysdate will have some hours and minutes, but after trunc it is defaulted to 00.00.00.000
By calling this
trunc(sysdate+1,'DAY')
you may see 16-FEB-14. You can't see the real result because Oracle doesn't display the minutes for you. If you call this
SELECT to_char(sysdate+1,'dd/mon/yyyy hh:mi:ss') FROM DUAL;
you will see all the time details. Trunk takes that off.
In other words, you have 3 effects here - sysdate + 1 - next date, Day - first day of the week, Trunc - hours, minutes, seconds, etc. off
see http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm
'DAY' truncates the date provided to the starting day of the week.
Note that depending on your locale this can also be Monday instead of Sunday.
sysdate + 1 just adds one day to the current date, this is probably done to make sure if you are sunday you get back the current sunday and not the previous one.
select to_char(sysdate+1,'dd-mon-yy hh24:mi:ss') from dual;----22-feb-14 02:10:03
select to_char(trunc(sysdate+1,'year'),'dd-mon-yy hh24:mi:ss') from dual;-----01-jan-14 00:00:00
select to_char(trunc(sysdate+1,'month'),'dd-mon-yy hh24:mi:ss') from dual; ---01-feb-14 00:00:00
select to_char(trunc(sysdate+1,'day'),'dd-mon-yy hh24:mi:ss') from dual; ---16-feb-14 00:00:00
Compare above queries outputs, hope this will help you.