MONTHS_BETWEEN error and to create flags - sql

SELECT months_between(TO_DATE(SYSDATE,'DD-MM-YYYY'),TO_DATE(DATE_COLUMN,'DD-MM-YYYY')) FROM TABLE_A;
1.I got an error which says, 'a non-numeric character was found where a numeric was expected'
Also, how to handle nulls.. I want to put a default date if the date_column is null in table_A.
2.
SELECT MONTHS_BETWEEN(TO_DATE(SYSDATE,'DD-MM-YYYY'),TO_DATE(DATE_COLUMN,'DD-MM-YYYY')) FROM TABLE_A;
After calculating months between dates, I want to categorize the records with date range with a case statement..
For example..
if months_between for set of records is 22..I want to put a flag,'0-24', for all those records..
similarly, if months_between is 34.. I want to put a flag,'24-48', for all the records which fall under this range..

To add to previous answer you can avoid null like this:
SELECT months_between(trunc(SYSDATE), nvl(TO_DATE(DATE_COLUMN,'DD-MM-YYYY'), sysdate))
If your DATE_COLUMN is date type than You don't need to use TO_DATE()
So You'll get somthing like this
SELECT months_between(trunc(SYSDATE), nvl(trunc(DATE_COLUMN), sysdate))
For the second part of Your question You may try something like this:
SELECT
trunc(months_between(trunc(SYSDATE), trunc(DATE_COLUMN))),
(trunc(months_between(trunc(SYSDATE), trunc(DATE_COLUMN))/24)*24)||'-'||((trunc(months_between(trunc(SYSDATE), trunc(DATE_COLUMN))/24)*24)+24)
FROM your_table

You don't need to convert sysdate to a date. Try this:
SELECT months_between(trunc(SYSDATE), TO_DATE(DATE_COLUMN,'DD-MM-YYYY'))
The problem is that the default format for a date in Oracle uses the month name. When you say to_date(sysdate, . . .), the first argument is converted to a string and then back to a date.
By the way, the trunc() is irrelevant, but you seemed to want to extract the day portion of sysdate so I left it in.
EDIT:
If date_column is already a date, just use:
SELECT months_between(trunc(SYSDATE), DATE_COLUMN)

This works, if you have null values in the date_column and want to pass a default date.
select months_between(SYSDATE,coalesce(DATE_COLUMN,to_date('01-01-2014','DD-MM-YYYY'))) DIFF from TABLE_A;

Related

Is there any ways to implement in oracle sql column default, like today() in excel?

Is there any possible way to make the column in sql oracle be like today() function in excel. Which will be show the today's date. I've tried using "SYSDATE" in the default value column but it does not change day by day means it only take the submission date.
default value column I need it changes to the current date.
You need to select the column. The default value is assigned when a row is inserted.
One method would use a view:
create view v_t as
select t.*, trunc(sysdate) as today
from t;
If you want the value in a particular format, either set the format in Excel or use to_char(), such as to_char(sysdate, 'MM/DD/YYYY').
Try this
SELECT TO_CHAR
(SYSDATE, 'MM-DD-YYYY HH24:MI:SS') "NOW"
FROM TableName;
I found that i can achieve that, if I : update tablename
set DATETODAY = TRUNC(SYSDATE) :
Is that efficient? Can we schedule the column to be update everyday/certain time

How to extract month number from date in Oracle

I have ID_BB_SECURITY column where the date value is stored in this column for example '20190801'.
I want to get month number from this field for example for August date i want to get 8.
I tried below query but it throws an error 'literal does not match':
select to_number(to_date(ID_BB_SECURITY),'mm') from BT_EXPORT
I am not sure if i have to ignore null values so as to avoid the error
If the value is a number or string then you can convert it to a date with an appropriate mask - which is what you are missing, and what is causing the error you are getting (as it's using your session's NLS_DATE_FORMAT setting, which apparently does not match the format of the data; but which you should not rely on anyway, as #MTO said in comments):
to_date(ID_BB_SECURITY, 'YYYYMMDD')
and then extract the month number from that:
select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
Or you could just use a substring:
select to_number(substr(ID_BB_SECURITY, 5, 2)) from BT_EXPORT;
Those assume a fixed consistent format, which is always a risky assumption when using the wrong data type. Ans if it's a number they are doing an implicit conversion from number to string, which you could turn into an explicit conversion for greater clarity.
If it's already a date - as it should be, of course - then you don't need the conversion:
select extract(month from ID_BB_SECURITY) from BT_EXPORT
If you have a number, you can use arithmetic to extract the month:
select mod(floor(20190801 / 100), 100)
from dual;
You could try converting the number date to a string, and then extracting the 5th and 6th characters:
SELECT
SUBSTR(TO_CHAR(ID_BB_SECURITY), 5, 2) AS mm
FROM BT_EXPORT;
But, it would be much better for you to use a proper date column. Then, you could use a less draconian method such as:
SELECT
TO_CHAR(ID_BB_SECURITY, 'mm') AS mm -- assuming date
FROM BT_EXPORT;
select to_number(to_char(to_date('20190801', 'yyyymmdd'), 'mm')) from dual
Try this one
select extract(month from to_date(ID_BB_SECURITY, 'YYYYMMDD')) from BT_EXPORT
This one convert number to date then extract month.
also
select extract(month from to_date('20190801', 'yyyymmdd')) from dual
Your date column has the value stored in the following format "yyyymmdd" where
yyyy is the year
mm the month
dd the day
So in order to return the number value of the month (mm) we can do as follows:
1: first transform the value from a number to a date using
to_date(20190801,'yyyymmdd')
2: get month using to_date operator
to_char( to_date(20190801,'yyyymmdd'), 'mm')

Compare YYYYMM with date range

I have a question on how to compare YYYYMM in Oracle SQL.
graduation_date is saved in string format like '200212'. I want to query rows with graduation_date from Jan 2007 to Jan 2010.
Here is my query:
select ids,
from table
where to_date(substr(graduation_date,1,6),'YYYYMM' between 'Jan-2007'and 'Jan-2010'
I got error
ORA-01858:a non-numeric character was found where a numeric was
expected
Can anyone can help figure this out? Many thanks!
I found a way to compare. Since the graduation_date is saved as vchar2 format like '20021200'.Default value is '00000000'. ONLY Year & Month is saved in Graduation_date. Here is my query:
select ids,
from table
where graduation_date between '20070100'and '20100100'
I tired some other ways advised but got ORA-01843: not a valid month error
select ids,
from table
where to_date(substr(graduation_date,1,6),'YYYYMM' between 'Jan-2007'and 'Jan-2010'
Thank you guys but just wondering why I can't use to_date to compare in this scenario?
Remove the comma after ids... Need a closing bracket after YYYYMM, is graduation_date of type char/varchar? If not then you can't do substr... Finally do to_date('200701', 'YYYYMM') and to other date also...
In Addition to delete comma here: select ids, and to add bracket after 'YYYYMM' here: To_date(substr(graduation_date,1,6),'YYYYMM' you also need to know:
You are seeing the dates in the format which is set in your NLS settings. Even after conversion you letting your NLS to show in already set format, in your case it's seems like MM/DD/YYYY, check by:
SELECT VALUE FROM nls_session_parameters WHERE parameter = NLS_DATE_FORMAT';
if you want to select date in your special format then after to_date function also use to_char function, like (if your data is in that graduation_date column like YYYYMM then no need to use substr function, else use as below):
SELECT to_char (to_date (SUBSTR (graduation_date, 1, 6), 'YYYYMM'), 'YYYYMM') FROM table;
So, if you want to select your data, then use below script (if your data is in that graduation_date column like YYYYMM then no need to use substr function, else use as below):
SELECT ids
FROM table
WHERE to_date (SUBSTR (graduation_date, 1, 6), 'YYYYMM')
BETWEEN to_date ('200701', 'YYYYMM') AND to_date ('201001', 'YYYYMM');
I don't suggest to use 'Jan-2012' (even if you convert by to_char function) with BETWEEN cause it will compare bytes of letter, not the month, so it's possible to get also June or July for each year if you use like this (and data only for Jan, not all months between them):
WHERE to_char (to_date (SUBSTR (graduation_date, 1, 6), 'YYYYMM'), 'Mon-YYYY')
BETWEEN 'Jan-2007' AND 'Jan-2010';
result something like this:
Jan-2007
Jun-2007
Jul-2007
Jan-2010 ...

Subtracting two date fields

I have two date fields and I am trying to subtract them to come up with the difference in days. I am using Oracle SQL server.
select LST_MOD_TS-EFF_DT as DATE_DIFF from TABLE1;
This gives me the following output:
+01 04:08:33.000000
I would like it formatted as '1' so I do not need the '+' or '-' sign, and I do not need the date portion in the return.
What is the best way to accomplish this?
Use the EXTRACT Function
SELECT EXTRACT(day FROM LST_MOD_TS)-(day FROM EFF_DT) AS DATE_DIFF
FROM TABLE1;

how to delete the records which is inserted 1 day ago

I dont have proper timestamp in table; is it possible to delete 1 day old logs even now?
I have a column name as SESSION_IN which is basically a VARCHAR datatype, and the value will be like
2013-10-15 02:10:27.883;1591537355
is there any way to trim the number after ; and is it possible to compare with "sysdate" identifier?
This SP should compare all the session IDs with current datetime and it should delete if it is older then 1 day.
You can igonre time part and convert date into required format somthing like this
SYSDATE - to_date('date_col','YYYY-DD-MM')
then you can perform operations.
Use the Substring function to extract the datetime portion from the record, then use convert to datetime to cast it to datetime, and then finally use datediff to check if it was inserted yesterday. Use all these caluses in a
DELETE FROM table
WHERE ___ query
For Oracle you could use something like this:
SELECT
TRUNC(to_timestamp(SUBSTR('2013-10-15 02:10:27.883;1591537355',1,
(
SELECT
instr('2013-10-15 02:10:27.883;1591537355', ';')-1
FROM
dual
)
), 'YYYY-MM-DD HH:MI:SS.FF'))
FROM
dual;
Which gives you just the date portion of your input string. Just subtract the amount of days you want to log at the end.
Hope following query helps you:
Select Convert(Datetime,Substring('2013-10-15 02:10:27.883;1591537355',1,23)), DateDiff(dd,Convert(Datetime,Substring('2013-10-15 02:10:27.883;1591537355',1,23)),Getdate())