Extract only the current year in oracle - oracle

I need to get the current year from the oracle db. For an example I need to return 2017 as the answer for the current year as a number type. I tried using following way.
select to_Number(sysdate, 'YYYY') from student s
But it not works. So what is the easiest way?

You need to_char instead of to_number
select to_char(sysdate, 'YYYY') from student;
That give a string though. you could apply to_number on it further to convert into number.
select to_number(to_char(sysdate, 'YYYY')) from student;
But there is better method using extract:
select extract(year from sysdate) from student;

Use extract
select extract(year from sysdate)
from dual;

get current year start date:
trunc (sysdate, 'yyyy')
select trunc (sysdate, 'yyyy'),SYSDATE from dual;
get current Month start date:
select trunc (sysdate, 'mm'),SYSDATE from dual;
select records in a month/year:
created_date between trunc (sysdate, 'mm') and sysdate;
created_date between trunc (sysdate, 'yyyy') and sysdate;

Related

Have error ORA-01861 when I want to change it to "date column type"

I have a table which calculates some measure base on the Date column type.
also, that should be store date as Persian calendar but at the end when I using TO_DATE function for changing its type have an ORA-01861 error on 19,20,21 days of the May while there is such date is already exist and the second month of Persian calendar has 31 days.
here is my query:
with a as
(select to_char(to_date('20190518', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190519', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190520', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190521', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL
UNION ALL
select to_char(to_date('20190522', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL)
SELECT TO_DATE(PERSIAN_DATE, 'YYYY/MM/DD') pers_date FROM A
my oracle database version is Oracle 12.2.0.1.0
You convert a sting to a DATE, then to a string and back again to a DATE, that's useless.
Try this one:
WITH a AS
(SELECT TO_DATE('20190518', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190519', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190520', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190521', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL
UNION ALL
SELECT TO_DATE('20190522', 'YYYYMMDD') PERSIAN_DATE
FROM DUAL)
SELECT to_char(PERSIAN_DATE, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') pers_date
FROM A
or shorter:
SELECT TO_CHAR(TO_DATE('20190517', 'YYYYMMDD')+LEVEL, 'YYYYMMDD', 'NLS_CALENDAR=PERSIAN') pers_date
FROM dual
CONNECT BY LEVEL <= 5;
Or use DATE literals and NLS session values:
ALTER SESSION SET NLS_CALENDAR = 'PERSIAN';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMMDD';
SELECT DATE '2019-05-17' + LEVEL pers_date
FROM dual
CONNECT BY LEVEL <= 5;
When you execute your select just for the 18th (that you were not having an issue with) and adding the raw value you will see it is returning
with a as
(select to_char(to_date('20190518', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL)
SELECT PERSIAN_DATE, TO_DATE(PERSIAN_DATE, 'YYYY/MM/DD') pers_date FROM A;
Persian Date pers_date
13980228 28/FEB/98 00:00:00
So oracle is trying discarding the first two characters and making the best date it can out of the rest (pretty sure this is not the correct Persian date).
So following the same logic when you run this for 19th (we can only get the raw value as to date will error)
with a as
(select to_char(to_date('20190519', 'YYYYMMDD'),
'YYYYMMDD',
'NLS_CALENDAR=PERSIAN') PERSIAN_DATE
from DUAL)
SELECT PERSIAN_DATE pers_date FROM A;
Persian Date
13980229
Following the same logic as above discard the first two characters and you get 29 Feb 1998... this is not a valid date.
As others have stated in the comments Oracle just stores the date it doesn't care about the calendar, you need to convert to the appropriate calendar for display.
For a good explanation of how oracle stores dates see
How are dates stored in Oracle?

ORA-00932: inconsistent datatypes: expected NUMBER got DATE in oracle stored procedure

I have below query which i am using in oracle stored procedure where i am getting error as
ORA-00932: inconsistent datatypes: expected NUMBER got DATE.
day_id column is Number datatype and the data is stored in this column like for e.g 20110822 and ltds column is date datatype and value is stored in this column for e.g 08-AUG-17. Both the column stored the actual date.
In my stored procedure i am putting this query in variable like below:
NESS_QUERY:= select t.day_id from M_TIME t
where TO_DATE (t.day_id, ''YYYYMMDD'') < trunc('''||LTDS||''') and
TO_DATE (t.day_id, ''YYYYMMDD'') >= trunc(sysdate, ''mm'') - case trunc('''||LTDS||''') when trunc(sysdate, ''mm'') then 1 else 0 end;
DBMS_OUTPUT.PUT_LINE (NESS_QUERY);
The output of DBMS_OUTPUT.PUT_LINE is below:
select t.day_id from M_TIME t
where TO_DATE (t.day_id, 'YYYYMMDD') < trunc('15-DEC-17') and
TO_DATE (t.day_id, 'YYYYMMDD') >= trunc(sysdate, 'mm') - case trunc('15-DEC-17') when trunc(sysdate, 'mm') then 1 else 0 end
If you have any influence over the choice of datatype for this column, please get it changed to be of DATE datatype. That will make things (like the query you're attempting to run) much easier.
As your column is not currently DATE datatype, if you want to compare the contents of the column to a date, you need to convert the column via to_date() along with an appropriate format mask. In your case, it looks like the format mask is yyyymmdd.
So your query should be something along the lines of:
select t.day_id
from m_time t
where to_date(t.day_id, 'yyyymmdd') >= trunc(sysdate, 'mm') - case trunc(ltds) when trunc(sysdate, 'mm') then 1 else 0 end;
below condition causing the error,
t.day_id >= trunc(sysdate, 'mm')
day_id is a number, trunc(sysdate, 'mm') returns date datatype
You should convert day_id to date before comparison, using TO_DATE
SELECT t.day_id
FROM M_TIME t
WHERE TO_DATE (t.day_id, 'YYYYMMDD') >=
TRUNC (SYSDATE, 'mm')
- CASE TRUNC (ltds) WHEN TRUNC (SYSDATE, 'mm') THEN 1 ELSE 0 END;
EDIT :
You don't need to use the ldts variable in your query, you may save it and use it in other places, but for query you could define it and reuse from cte.
WITH l AS (SELECT TRUNC (LOAD_DATE) LDTS FROM JOB_EXE)
SELECT t.day_id
FROM M_TIME t CROSS JOIN l
WHERE TO_DATE (t.day_id, 'YYYYMMDD') < l.LDTS
AND TO_DATE (t.day_id, 'YYYYMMDD') >=
TRUNC (SYSDATE, 'mm')
- CASE l.LDTS WHEN TRUNC (SYSDATE, 'mm') THEN 1 ELSE 0 END
where (t.day_id, 'YYYYMMDD') < trunc('31-DEC-23') and
TO_DATE (t.day_id, 'YYYYMMDD') >= trunc(sysdate, 'mm') - case trunc('01-Jan-23') when trunc(sysdate, 'mm') then ('Yes') else ('No') end

concatenating sysdate with fixed time in oracle

I want to concatenate sysdate with my own time. Below is the query i have tried, but I am getting year as 0016 instead of 2016.
Are there any other ways to get the result like below?
Query:
select to_date(sysdate || ' 02:50:00','dd-mon-yyyy hh24:mi:ss') as MyTime from dual
Output:
MYTIME
3/12/0016 02:50:00 AM
One way
Convert SYSDATE to a string
Append your fixed time element
Convert back to a date
Put it altogether like this:
to_date(to_char(sysdate,'YYYY-MM-DD')||' 02:50:00','YYYY-MM-DD HH24:MI:SS' )
Alternative way: use arithmetic.
Strip the real time from SYSDATE
Add the number of seconds ((60*60*2)+(50*60)/(60*60*24)
Include your workings or not:
trunc(sysdate) + ( 10200 / 86400)
There is a third way: use an INTERVAL (basically a variant of the second way).
SQL> select trunc(sysdate) + to_dsinterval('0 02:50:00') as mytime
2 from dual
3 /
MYTIME
------
2016-03-12 02:50:00
SQL>
Try this
SELECT TO_DATE(TO_CHAR(SYSDATE, 'DD-MON-YYYY') || ' 08:00:00', 'DD-MON-YYYY HH:MI:SS') FROM DUAL;
Just change SYSDATE to TO_CHAR(SYSDATE, 'DD-MON-YYYY')
I did this:
SELECT TO_CHAR(
TO_DATE(TO_CHAR(SYSDATE, 'DD-MON-YYYY') || ' 08:00:00', 'DD-MON-YYYY HH:MI:SS')
,'DD-MON-YYYY HH:MI:SS') from dual;
and got
12-MAR-2016 08:00:00
as a result.

to_date function with sysdate

select TO_CHAR(to_date(sysdate, 'DD-MON-YYYY'), 'DAY') FROM DUAL;
When I run this query the output was : SUNDAY. But we know today is Tuesday(1-1-2013).
And
then changed the query as
select TO_CHAR(to_date('01-JAN-2013', 'DD-MON-YYYY'), 'DAY') FROM DUAL;
answer was :TUESDAY.
then Changed query as
select TO_CHAR(to_date(sysdate+1, 'DD-MON-YYYY'), 'DAY') FROM DUAL;
answer is :MONDAY.
When I using the sysdate why it is show SUNDAY as output?
I am new in oracle db. Please help me.
use this:
select TO_CHAR(sysdate, 'DAY') FROM DUAL;
you are using this :
to_date(sysdate, 'DD-MON-YYYY')
which is giving you date=1/1/0013 which is sunday
Please refer the documentation for sysdate here. Sysdate is already a date data type.
Your example query is inappropriate as to_date function takes first parameter as String not date.
Try the simple query below:
select TO_CHAR(sysdate, 'DAY') FROM DUAL;
This should return TUESDAY as output.
To_date is used to convert a strin to date. As sysdate is already a date, one must not add add to_date.

Date function on oracle

I've got a question about date function on oracle.
I have the following table
statistic_table(
pages AS varchar(10),
date_created AS date
);
I have the following sql
SELECT COUNT(*) FROM statistic_table WHERE date_created BETWEEN sysdate-5 AND sysdate-1
and
SELECT COUNT(*) FROM statistic_table WHERE date_created BETWEEN to_date('12-AUG-2011') AND to_date('16-AUG-2011');
the question is, why is it return different numbers. assuming sysdate-5 returns 12-aug-2011 and sysdate-1 returns 16-aug-2011
Any help would be much appreciated!
Cheers,
sysdate - 5 will give you a date with the current time. So if I ran it at 1pm precisely, the query would be equivalent to:
select (*)
FROM statistic_table
WHERE date_created BETWEEN to_date('12-Aug-2011 13:00:00')
AND to_date('16-Aug-2011 13:00:00')
whereas the second query is:
select (*)
FROM statistic_table
WHERE date_created BETWEEN to_date('12-Aug-2011 00:00:00')
AND to_date('16-Aug-2011 00:00:00')
you should probably try this instead:
select (*)
FROM statistic_table
WHERE date_created BETWEEN trunc(sysdate) -5
AND trunc(sysdate) -1
A date in Oracle is a point in time with a precision of a second.
SYSDATE returns the current date and time and is therefore not the same as to_date('17-AUG-2011'):
SQL> SELECT to_char(sysdate, 'dd-mon-yyyy hh24:mi:ss') FROM DUAL;
TO_CHAR(SYSDATE,'DD-MON-YYYYHH
------------------------------
17-aug-2011 15:52:13
Use the TRUNC function if you only want the date component:
SQL> SELECT to_char(trunc(sysdate), 'dd-mon-yyyy hh24:mi:ss') FROM DUAL;
TO_CHAR(TRUNC(SYSDATE),'DD-MON
------------------------------
17-aou-2011 00:00:00
Because SYSDATE includes a time component, so if the current time is 11:22:33, then
SELECT COUNT(*) FROM statistic_table
WHERE date_created BETWEEN sysdate-5 AND sysdate-1
is actually equivalent to
SELECT COUNT(*) FROM statistic_table
WHERE date_created BETWEEN to_date('12-AUG-2011 11:22:33','DD-MON-YYYY HH24:MI:SS')
AND to_date('16-AUG-2011 11:22:33','DD-MON-YYYY HH24:MI:SS')
To avoid the time component do this:
SELECT COUNT(*) FROM statistic_table
WHERE date_created BETWEEN TRUNC(sysdate)-5 AND TRUNC(sysdate)-1
An Oracle DATE always has a day and a time component.
sysdate-5 returns a date exactly 5 days ago. If today is August 17 at 10 AM, for example, sysdate-5 returns August 12 at 10 AM.
to_date('12-AUG-2011', 'DD-MON-YYYY'), on the other hand, returns August 12 at midnight. So it returns a date that is 10 hours earlier than sysdate-5.
sysdate auto returns with a time component as mentioned by the previous answers.
When using to_date it is converting a string to a date. With this being said you can pass in parameters to make it return the same thing.
Have a look at this link that explains it.
to_date parameters

Resources