Oracle Julian day of year - sql

how can I select Julian day of year in Oracle database?
I tried:
select to_char(sysdate, 'J') from dual;
Which gives me the number of days since January 1, 4712 BC. But I would need the number of days since 1.1. of current year.

If you check the TO_CHAR (datetime) documentation you get a link to "Format Models" with a comprehensive list of available formats. I guess you want this:
DDD Day of year (1-366)

SELECT TO_CHAR(SYSDATE, 'DDD') from DUAL;

One way would be to use:
select sysdate - trunc(sysdate,'yyyy') from dual
'Trunc' cuts everything except the year and returns 01/01/2014, subtracted by the sysdate returns numbers of days since 1st of january.

Use sql select trunc(sysdate)+1 - trunc(sysdate,'yyyy') from dual. you will get an even number

Related

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

Retrieve number of the day sql query

I wan't to retrieve the number of the day using an SQL request but I found that I retrieve the number of day since the 01-01-4712 using this query:
SELECT TO_CHAR(TRUNC(SYSDATE),'J') FROM DUAL;
Is there any other query I may use?
Use to_char() to convert your date. Format mask 'DDD' returns the day of the year.
select to_char(sysdate, 'DDD') from dual;
select to_char(to_date('1/1/2014', 'MM/DD/YYYY'), 'DDD') from dual;
Some more info on various formats: http://www.techonthenet.com/oracle/functions/to_char.php
After investigations I found that we can use this query to obtain the number of day in the current year:
select to_date(sysdate) - trunc(sysdate,'YYYY') from dual

How would you truncate or limit the results of a date result you are adding time to? (Oracle SQL)

So I am doing a homework project where I have to display the current date, and then the date for three months from now, which I have done with this:
SELECT CURRENT_DATE AS "Today's Date", LOWER(ADD_MONTHS(CURRENT_DATE, 3)) AS "Today, Three Months Hence" FROM dual;
and again with this:
SELECT CURRENT_DATE AS "Today's Date", LOWER(CURRENT_DATE + INTERVAL '3' MONTH)AS "Today, Three Months Hence" FROM dual;
results:
Today's Date
05-FEB-14
Today, Three Months Hence
05-may-14
What I am wondering is if there is a way to display the results of the future date where it only shows the month and nothing else, (i.e. no day or year). Is this possible in Oracle, or am I just looking to try the impossible?
You just need to specify the display format, which you should really do anyway instead of relying on your session defaults:
SELECT TO_CHAR(CURRENT_DATE, 'DD/MM/YYYY') AS "Today's Date",
TO_CHAR(ADD_MONTHS(CURRENT_DATE, 3), 'YYYY-MM-DD')
AS "Today, Three Months Hence",
TO_CHAR(ADD_MONTHS(CURRENT_DATE, 3), 'Month') AS "Three Months Hence"
FROM dual;
| TODAY'S DATE | TODAY, THREE MONTHS HENCE | THREE MONTHS HENCE |
|--------------|---------------------------|--------------------|
| 06/02/2014 | 2014-05-06 | May |
Simple SQL Fiddle.
The available date format model elements are shown in the documentation.
A date value is actually stored as a number in database, not a character string. What you see in your result is the default date format interpretation of your session.
To change the way your date fields are displayed, you need to use to_char function.
select to_char(sysdate, 'MM') from dual;
'MM' parameter here stands for month, which is what you asked. It is a format string to convert a date into a character string. For a list of your options with format string, a simple google search will help you.
OK, I was looking at an example about to_char and finally sorted it out:
SELECT CURRENT_DATE AS "Today's Date", TO_CHAR(ADD_MONTHS(CURRENT_DATE, 3), 'month') AS "Today, Three Months Hence" FROM dual;
This is similar to the answer provided by Alex. I did notice that when I type in month in lower case the result is also in lower case, and when it type it in as MONTH, in upper case, the result is then in upper case, which is good to know. This wasn't required, but I was curious.

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

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;

Oracle to_date function with quarter-format

I need to find some records created in a range of quarters. For example, I'm looking for all records created between the 4th quarter of 2008 and the 1st quarter of 2010. I have this in my WHERE-clause:
...and r.record_create_date between to_date('2008 4','YYYY Q')
and to_date('2010 1','YYYY Q')
but Oracle says: ORA-01820: format code cannot appear in date input format. The Q is a valid date format symbol, so I'm not sure what's happened. Is this even a valid way to find values in between calender quarters, or is there a better way?
Also interesting, and possibly related, if I execute this:
select to_date('2009','YYYY') from dual;
The value displayed in my IDE is 2009-08-01. I would have expected 2009-08-04, since today is 2010-08-04.
This:
select to_date('2009 1','YYYY Q') from dual;
of course, fails.
(Oracle 10g)
Oracle says: ORA-01820: format code cannot appear in date input format. The Q is a valid date format symbol, so I'm not sure what's happened.
See the second column of table 2.15 at http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34948. Not all format elements are allowed when converting to dates, timestamps, etc.
I recommend against using between for date range checks. People often will miss values within the ending day that the expect to be included. So I would translate:
and r.record_create_date between to_date('2008 4','YYYY Q')
and to_date('2010 1','YYYY Q')
To
and to_date('2008-10-01', 'YYYY-MM-DD') <= r.record_create_date
and record_create_date < to_date('2010-04-01', 'YYYY-MM-DD') -- < beginning of 2Q2010.
Someone asked the same question on OTN: http://forums.oracle.com/forums/thread.jspa?threadID=1081398&tstart=255
The crux of the issue is that you can not specify "Q" in the TO_DATE function.
Given that you're already specifying a portion of the date, why not provide the entire date? Mind too that to_date('2010 1','YYYY Q') would give you Jan 1st, 2010 when you really want March 31st, 2010... at a second to midnight.
Since the relationship between quarters to months is one-to-many, it doesn't make sense to do TO_DATE('2008 1', 'yyyy q'); what date should be returned? The first of the quarter, the end of the quarter, ...? (On the other hand, converting a date to a quarter - like TO_CHAR(SYSDATE, 'yyyy q') makes sense because a specific date only exists in one quarter.)
So, if you do want a query that looks for a date that falls between two quarters, you will have to "rolll your own" (explicitly stating the dates of the start/end of a quarter.)
As a side note, in case anyone is considering not using TO_DATE please do not use things like: WHERE date_value BETWEEN 'date string1' and 'date string2' without the TO_DATE function. It assumes a default date format and under certain situations can avoid potentially useful indexes altogether.
Below is one example where the same query can have a different result.
select sysdate from dual where sysdate between '1-Jan-10' and '31-Dec-10';
SYSDATE
---------
04-AUG-10
SQL> alter session set nls_date_format = 'YYYY-MM-DD';
Session altered.
SQL> select * from dual where sysdate between '1-Jan-10' and '31-Dec-10';
no rows selected
(Notice that in the second instance no error is returned. It just assumes Jan 10, 0001 and Dec. 10th, 0031.)
I think the best way is to just input the quarter start date and quarter end dates without even bothering with to_date. I think if you use
between '1-Jan-10' and '31-Dec-10'
for example, then you don't (in Oracle I believe) need to_date and it isn't much more difficult than typing in the quarter number
To calculate in Oracle the first day of a quarter and the last day of a quarter from the year and quarter:
I Use the fact
start_month= -2 + 3 * quarter
last_month = 3 * quarter
variable v_year number
variable v_quarter number
exec :v_year :=2017
exec :v_quarter:=4
select :v_year as year,
:v_quarter as quarter,
to_date(:v_year||to_char(-2+3*:v_quarter,'fm00'),'yyyymm') as quarter_start,
last_day(to_date(:v_year||to_char(3*:v_quarter,'fm00')||'01 23:59:59','yyyymmdd hh24:mi:ss')) as quarter_end
from dual a;
YEAR|QUARTER|QUARTER_START |QUARTER_END
2017| 4|2017-10-01 00:00:00|2017-12-31 23:59:59