NO OUTPUT WHILE CONVERTING TO_CHAR(HIRE_DATE,'MONTH') - sql

Why does the first query returns no rows when I search employees hired in May or November but the second one does? my default date format is rr-mm-dd .
Also is there a way to search if I don't know the default date format?
SELECT EMPLOYEE_ID,LAST_NAME||', '||FIRST_NAME"Full Name",JOB_ID,HIRE_DATE
FROM EMPLOYEES WHERE UPPER(TO_CHAR(HIRE_DATE,'MONTH')) IN ('MAY','NOVEMBER');
SELECT EMPLOYEE_ID,LAST_NAME||', '||FIRST_NAME"Full Name",JOB_ID,HIRE_DATE
FROM EMPLOYEES WHERE TO_CHAR(HIRE_DATE,'MM') IN ('11','05');

The problem with TO_CHAR is that it won't trim trailing whitespaces.
You should use
SELECT EMPLOYEE_ID,LAST_NAME||', '||FIRST_NAME"Full Name",JOB_ID,HIRE_DATE
FROM EMPLOYEES WHERE TRIM(TO_CHAR(HIRE_DATE,'MONTH') IN ('MAY','NOVEMBER');
You also don't need UPPER if you are already using capital MONTH in to_char.

Your query has several issues.
When you use TO_CHAR(HIRE_DATE,'MONTH') then month name is padded with space characters, try TO_CHAR(HIRE_DATE,'"MONTH"') to see the effect. It should return "MAY "
Another issue is the current user session NLS_DATE_LANGUAGE which determines the language of month names.
If you insist to use the month names then use
WHERE TO_CHAR(HIRE_DATE,'fmMONTH', 'NLS_DATE_LANGUAGE = American') IN ('MAY','NOVEMBER')
or
WHERE TRIM(TO_CHAR(HIRE_DATE,'MONTH', 'NLS_DATE_LANGUAGE = American')) IN ('MAY','NOVEMBER')
However, the best way would be not using the names but month numbers. Instead of TO_CHAR(HIRE_DATE,'MM') you could also use EXTRACT(MONTH FROM HIRE_DATE) which returns the month as number.

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.

Calculate age for specific year in oracle sql

Please i need help about oracle sql! I try to get age from birth date but it's not working from the year 1940 ! My query is
select months_between(sysdate, '11/01/40') from dual
and the answer i get is -19!
The calculation works up to year 1950
If you use a proper ANSI date literal, with the full year component, it works:
SELECT MONTHS_BETWEEN(sysdate, date '1940-01-11') FROM dual;
Assuming your dates are stored as text DD/MM/YY, you may use TO_DATE instead:
SELECT MONTHS_BETWEEN(sysdate, TO_DATE(date_col, 'DD/MM/YY)
FROM yourTable;
If the above does not work, it could be because 40 is being interpreted as 2040, not 1940. Please use the full 4 digit date whenever possible, and also avoid storing your dates as text.

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

Validate a date comprised of 3 fields in PLSQL

I am not an expert in PLSQL. Normally to validate a date I would do something like this:
dt_variable := TO_DATE(<INPUT_DATE>,<DATE_FORMAT>)
and if it returned an error I would know the date is invalid. I have a different requirement now though. The day, month, and year are all separate text fields. I need to make sure the day is valid from 1-31, month is JAN-DEC (3 letter texts) and year is in the format YYYY. I also need to check if the date is valid, for instance no June 31st. Since I have 3 fields ow I can't use the to_date function is there any other function i can use to accomplish this. I have searched, but could not find anything and am hoping a sql expert might now of a method.
Don't try to validate the separate elements at all; concatenate them together with the appropriate separator, and treat the combined value as one; e.g.:
to_date(l_day || '/' || l_month || '/' || l_year, 'DD/MON/YYYY')
Using month names or abbreviations can be a problem as you're relying on the NLS settings matching. If you know the values will always be English you can specify the NLS_DATE_LANGUAGE with the optional third argument to to_date. It's often safer to use month numbers; and an unambiguous date format like YYYY-MM-DD. It doesn't sound like you have control over that though.

Format date where the position of the parts is variable

We have a file that needs to be imported that has dates in it. The dates are in a format that I have not seen before and the day part can vary in length (but not the month or year seemingly) and position based on wether the number is double digit or not, i.e.
Dates:
13082014 is 13th February 2014
9092013 is 9th September 2013
The current script tries to substring the parts out, but fails on the second one as there is not enough data. I could write an if or case to check the length, but is there a SQL format that can be used to reliably import this data?
To clarify this is MSSQL and the date format is ddmmyyyy or dmmyyyy
One of the simple way is using STUFF.
example:
select STUFF(STUFF('13082014 ',3,0,'/'),6,0,'/');
//result: 13/08/2014
Good luck.
LPAD a zero when it is missing so to always get an eight character date string. Here is an example with Oracle, other DBMS may have other string and date functions to achieve the same.
select to_date(datestring, 'ddmmyyyy')
from
(
select lpad('13082014', 8, '0') as datestring from dual
union all
select lpad('9092013', 8, '0') as datestring from dual
);
Result:
13.08.2014
09.09.2013
you can convert the dates to a relevant date format then import data(based on the dateformat change the logic).
something like this :
select Convert(varchar(10),CONVERT(date,YourDateColumn,106),103)