What is the difference TO_DATE('21-09-1989','DD-MM-YY') and TO_DATE('21-09-89','DD-MM-YY')? - sql

Below query returns the result:
SELECT *
FROM EMPLOYEES
WHERE HIRE_DATE = TO_DATE('21-09-1989','DD-MM-YY');
where as if I change the date from 21-09-1989 to 21-09-89 returns nothing.
SELECT *
FROM EMPLOYEES
WHERE HIRE_DATE = TO_DATE('21-09-89','DD-MM-YY');
What is the issue here?

If you use the YY as the year then it returns the year which is in the current century i.e. 2000-2099. In your case -- 2089
If you use the YYYY then the exact year is returned. -- in your case 1989
If you use RR then the year which is between 1950-2049 is returned. -- in your case 1989
So
TO_DATE('21-09-1989','DD-MM-YY') --> 21-09-1989
-- oracle is smart to detect the given format as YYYY
TO_DATE('21-09-89','DD-MM-YY') --> 21-09-2089
-- as 2089 is between 2000-2099
TO_DATE('21-09-89','DD-MM-RR') --> 21-09-1989
-- as 1989 is between 1950-2049

TO_DATE('21-09-89','DD-MM-YY')
evaluates to Sep 21 2089

As already explained in other answer about the difference between 'YY' and 'YYYY' format and its implications. You could easily avoid problems by using the ANSI DATE literal:
DATE '1989-09-21'
The ANSI date literal contains no time portion, and must be specified in exactly this format ('YYYY-MM-DD').
Also, HIRE_DATE is a DATE data type which also has a time portion. Therefore, your WHERE condition might not return correct values:
WHERE HIRE_DATE = TO_DATE('21-09-1989','DD-MM-YY')
To remove the time portion you must use TRUNC to compare with only date portion:
WHERE TRUNC(HIRE_DATE) = DATE '1989-09-21'

Related

Filtering based on the month someone was born

Currently trying to create a query that filters on the month that someone was born but its returning errors.
I want it to display everyone who was born on 05 month.
SELECT "Person Names"."Full Name" saw_0,
   "Person"."Person Date Of Birth" saw_1
FROM "Workforce Management - Person Real Time"
WHERE "Person"."Person Date Of Birth" = date '%-05-%'
DATE followed by a string is a date literal. The string must have the format yyyy-mm-dd. The expression date '%-05-%' is hence syntactically incorrect.
You can, however, extract a month from a date:
WHERE EXTRACT(MONTH FROM "Person"."Person Date Of Birth") = 5
Considering "Person"."Person Date Of Birth" is of type DATE you could simply do:
WHERE TO_CHAR("Person"."Person Date Of Birth",'MM') = '05'
Update:
WHERE TO_CHAR("Person"."Person Date Of Birth",'MM') = TO_CHAR(SYSDATE,'MM')
This will give you the people born in the current month.
You can use EXTRACT to check the month. In case your column is already of type date, this will do:
SELECT * FROM yourtable WHERE EXTRACT(MONTH FROM datecolumn) = 5;
If the column is of type varchar, you can cast it as date and then do the same:
SELECT * FROM yourtable WHERE
EXTRACT(MONTH FROM TO_DATE(varcharcolumn,'dd.mm.yyyy')) = 5;
Please see a simple example here: db<>fiddle

Oracle SQL Extract Year from VARCHAR2

Please don't roast me for not being able to figure this out. I'm a beginner with SQL and I've been trying to find a solution and make it work for at least a couple hours in total. I know the date fields should be stored as dates, not varchar2, but I have no control over that.
EXTRACT ( YEAR FROM ( TO_DATE ( 'ENTDAT', 'MM/DD/YYYY' ))) = 2018
"ORA-01858: a non-numeric character was found where a numeric was expected"
I feel like I'm close with this, just missing some magic and hoping for an assist here.
'ENTDAT' is a string literal.
ENTDAT (without the quotes) could be a column name.
So if your column name is ENTDAT you probably wanted:
SELECT *
FROM your_table
WHERE EXTRACT ( YEAR FROM ( TO_DATE ( ENTDAT, 'MM/DD/YYYY' ))) = 2018
If your string is in that format, just use like:
where enddate like '%2018'
Of course, you should be storing a date as a date. Then you can use:
where enddate >= date '2018-01-01' and
enddate < date '2019-01-01'

How to check if column having date of birth format has yyyymmdd in sql server?

How to check if column having date of birth format has yyyymmdd in sql server?
You can verify with the ISDATE Function, but I don't know which SQL edition do you have
Example
select ISDATE ( 1 )
------------------
0
select ISDATE ( 11111111 )
------------------
0
select ISDATE ( 20170501)
------------------
1
You can use:
select (case when try_convert(date, dob) is not null and
try_convert(int, dob) is not null
then 1 else 0
end)
I'm not 100% sure, but I think that yyyymmdd is the only format that will generally pass both conditions. Note: There is no way to know if 20170601 is really June 1st or Jan 6th, so this cannot actually validate the contents of the field.
But why do you care what the format is, so long as you can convert it to a date? You should then change the column to a date type and henceforth know that the "format" is correct.
If the column is a Char type (yuck) then Like '[12][0-9][0-9][0-9][0-1][0-9][0-3][0-9]' (off the top of my head)
If it's a DateTime then who cares, it's a date.

Selecting YYYYMM of the previous month in HIVE

I am using Hive, so the SQL syntax might be slightly different. How do I get the data from the previous month? For example, if today is 2015-04-30, I need the data from March in this format 201503? Thanks!
select
employee_id, hours,
previous_month_date--YYYYMM,
from
employees
where
previous_month_date = cast(FROM_UNIXTIME(UNIX_TIMESTAMP(),'yyyy-MM-dd') as int)
From experience, it's safer to use DATE_ADD(Today, -1-Day(Today)) to compute last-day-of-previous-month without having to worry about edge cases. From there you can do what you want e.g.
select
from_unixtime(unix_timestamp(), 'yyyy-MM-dd') as TODAY,
date_add(from_unixtime(unix_timestamp(), 'yyyy-MM-dd'), -1-cast(from_unixtime(unix_timestamp(), 'd') as int)) as LAST_DAY_PREV_MONTH,
substr(date_add(from_unixtime(unix_timestamp(), 'yyyy-MM-dd'), -1-cast(from_unixtime(unix_timestamp(), 'd') as int)), 1,7) as PREV_MONTH,
cast(substr(regexp_replace(date_add(from_unixtime(unix_timestamp(), 'yyyy-MM-dd'), -1-cast(from_unixtime(unix_timestamp(), 'd') as int)), '-',''), 1,6) as int) as PREV_MONTH_NUM
from WHATEVER limit 1
-- today last_day_prev_month prev_month prev_month_num
-- 2015-08-13 2015-07-30 2015-07 201507
See Hive documentation about date functions, string functions etc.
below works across year boundaries w/o complex calcs:
date_format(add_months(current_date, -1), 'yyyyMM') --previous month's yyyyMM
in general,
date_format(add_months(current_date, -n), 'yyyyMM') --previous n-th month's yyyyMM
use proper sign for needed direction (back/ahead)
You could do (year('2015-04-30')*100+month('2015-04-30'))-1 for the above mentioned date, it will return 201503 or something like (year(from_unixtime(unix_timestamp()))*100+month(from_unixtime(unix_timestamp())))-1 for today's previous month. Assuming your date column is in 'yyyy-mm-dd' format you can use the first example and substitute the date string with your table column name; for any other format the second example will do, add the column name in the unix_timestamp() operator.
Angelo's reply is a good start but it returns 201500 if the original date was 2015-01-XX. Building on his answer, I suggest using the following:
IF(month(${DATE}) = 1,
(year(${DATE})-1)*100 + 12,
year(${DATE})*100 + month(${DATE})-1
) as month_key
provided you get rid of those hyphens in your input string , previous date's month id in YYYYMM format you can get by:-
select if( ((${hiveconf:MonthId}-1)%100)=0 ,${hiveconf:MonthId}-89,${hiveconf:MonthId}-1 ) as PreviousMonthId;

oracle date range

using a Oracle 10g db I have a table something like this:
create table x(
ID NUMBER(10) primary key,
wedding DATE NOT NULL
);
how can I
select * from x where wedding is in june 2008???
I know it is probably an easy one but I couldn't find any satisfying answer so far.
Help is very much appreciated.
Use:
SELECT *
FROM x
WHERE x.wedding BETWEEN TO_DATE('2008-JUN-01', 'YYYY-MON-DD')
AND TO_DATE('2008-JUL-01', 'YYYY-MON-DD')
Use of TO_DATE constructs a date with a time portion of 00:00:00, which requires the end date to be one day ahead unless you want to use logic to correct the current date to be one second before midnight. Untested:
TO_DATE('2008-JUN-30', 'YYYY-MON-DD') + 1 - (1/(24*60*60))
That should add one day to 30-Jun-2008, and then subtract one second in order to return a final date of 30-Jun-2008 23:59.
References:
TO_DATE
This is ANSI SQL, and supported by oracle as of version 9i
SELECT *
FROM x
WHERE EXTRACT(YEAR FROM wedding) = 2008
AND EXTRACT(MONTH FROM wedding) = 06
Classic solution with oracle specific TO_CHAR():
SELECT *
FROM x
WHERE TO_CHAR(wedding, 'YYYY-MMM') = '2008-JUN'
(the latter solutions was supported when dinosaurs still walked the earth)