Compare YYYYMM with date range - sql

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 ...

Related

Oracle SQL: Transpose Columns to Rows After Using Extract

I have a table with column DATE. Date is 'dd/mm/yyyy' and I want only days. So I try with extract and return what I need, but I what using transpose for column to row.
The select statement is:
select EXTRACT (DAY FROM "DATE") DAY
from people;
Is this thing possible?
Thank you!
If you have a string, then just use the leftmost two characters:
select substr("DATE", 1, 2) as day
That said, you should not be storing dates as strings. It is wrong, wrong, wrong. You cannot use the built-in date/time functions. You cannot use inequality comparisons either. Fix your data model.
The date format doesn't matter. It is linked to your NLS local settings and this is how you see this.
To have it generic and extract DAY from the date do this:
select to_char(sysdate, 'DD') from dual;
Would return 07 since it's September 7th 2020.

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')

Convert date to month year format and pass it in the query

I have a BIRT report where user will be entering the dates in dd-mm-yyyy format however I need to convert dd-mm-yyyy to MON-YYYY format.
I have tried to use VARCHAR_FORMAT(FIELDNAME,'MON-YYYY') however it doesn't work.
select …….
where VARCHAR_FORMAT(fieldname,'MON-YYYY') = '2017-05-15';
User would end the date as
15/05/2017
The value present in the database for this field is 2017-05-15 07:30:00.0
update
Apparently the column is not a string but a datetime which means the conversion is only
to_date(fieldname, 'MON-YYYY')
But if the column is used in a Where clause it shouldn’t be converted at all.
——
Use to_date and to_char to first convert your string to a date and then back to a string with the right format
to_char(to_date(fieldname, 'DD-MM-YYYY'), 'MON-YYYY')
select *
from table (values
timestamp('2017-05-15-07.30.00')
) t(fieldname)
where
fieldname between to_date('15/05/2017', 'DD/MM/YYYY') and to_date('15/05/2017', 'DD/MM/YYYY') + 1 day
--date(fieldname) = to_date('15/05/2017', 'DD/MM/YYYY')
;
You may run it as is.
Both cases work, but to use the 2-nd one efficiently, you must create an index by the date(fieldname) expression (since db2 10.5) or add generated always column to the table with the same expression and index on it.

MONTHS_BETWEEN error and to create flags

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;

Modify an existing to_char date format

Oracle SQL automatically converts my field D.START_DT to the following format:
TO_CHAR(D.START_DT,'YYYY-MM-DD')
Which makes it difficult for me to modify my own date format.
I've tried wrapping another TO_CHAR around it with no luck.
TO_CHAR(TO_CHAR(D.START_DT,'YYYY-MM-DD'), 'MM/DD')
And I've tried SUBSTR to select certain characters, with no luck. I think the hyphen is getting int he way.
SUBSTR(TO_CHAR(D.START_DT,'YYYY-MM-DD'), 6, 7) || '/' || SUBSTR(TO_CHAR(D.START_DT,'YYYY-MM-DD'), 9, 10)
What is the work around for this?
I agree with RMAN Express and see no problems converting dates to any format you need...
In case you still have problems try this (first to_char() in outer query is optional):
SELECT to_char(to_date(some_date, 'YYYY-MM-DD'), 'MM/DD') final_date
FROM
(
SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD') some_date -- this is your "auto converted" date
FROM dual
)
/
A DATE datatype has no format. When you see a date printed on a screen, there was something that APPLIED the format you see. Could be a "default" in the program you are using (like SQL Developer) or your NLS setting, etc. But, a DATE datatype has no format. So, you have complete control over the format you see on screen.
The simplest is to use the TO_CHAR function:
select TO_CHAR(D.START_DT,'YYYY') from dual;
returns just the four digit year.
See TO_CHAR date format options.
http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements004.htm#CDEHIFJA
You should always supply the format in your code and not rely on some other "default" to supply it.