Updating dates from 19XX to 20XX in Oracle - sql

I have a table where dates have been incorrectly entered as 19XX rather than 20XX.
Is it possible to have an update query that will amend any value in a particular field from 19XX to 20XX (UK date format) where the original date is less than 01/01/2000?
For example
ID FieldA
123 23/11/1917
would become
ID FieldA
123 23/11/2017

Assuming that you may have correct date in the latter half of the 20th century and it is only the earlier half of the century you need to update (please confirm this) then:
UPDATE table_name
SET date_column = ADD_MONTHS( date_column, 12 * 100 )
WHERE date_column >= DATE '1900-01-01'
AND date_column < DATE '1950-01-01';
If you do want to change the dates for all years in the 20th century then:
UPDATE table_name
SET date_column = ADD_MONTHS( date_column, 12 * 100 )
WHERE date_column >= DATE '1900-01-01'
AND date_column < DATE '2000-01-01';
Note: you need to use the ADD_MONTHS function rather than adding INTERVAL '100' YEAR(3) since there are dates in the 20th century that are not in the 21st century (i.e. 1900-02-29).

You can take advantage of shortened YY date format. To quote the docs:
If you use the TO_DATE function with the YY datetime format element,
then the year returned always has the same first 2 digits as the
current year.
Therefore, to_date(to_char(fieldA, 'ddmmyy'), 'ddmmyy') should do what you need. Be careful though, if there are dates with years less than 1900 or over 2100, they'll be converted as well.

If FieldA is a date, then you can do:
select (case when fieldA < date '2000-01-01'
then fieldA + interval '100' year(3)
else fieldA
end)

Related

How to display the field date (type of data date) in the last 3 months

I have this query:
select date
from datetime
where tgl_valuta > TO_DATE('01/01/2019', 'dd-mm-yyyy');
I want to query for the display date in the last three months.
Use ADD_MONTHS
select * from datetime where tgl_valuta > add_months(sysdate, -3)
This checks for exactly 3 months behind the current date (sysdate). If you want to compare from first day of the 3rd previous month, you may add TRUNC with MM option
> TRUNC(add_months(sysdate, -3),'MM')

oracle compare a date with the current date

I have to convert a column to a date and then compare the month of the column with the current month.
The column looks like this :
Date
0117
0217
0317
..
I know how to convert it but cant compare it.
select date,to_date(date, 'mmyy')
from table
where ????
any ideas?
You can convert the value to a date using to_date():
select to_date(mmyy, 'MMYY')
from t;
Note that I renamed the column mmyy to clarify what it contains.
This returns the first day of the month.
The result of to_date() can then be compared to the current date. For instance, to match the first of date of the month:
where to_date(mmyy, 'MMYY') = trunc(sysdate)
If you want to match everything in the month, just use an appropriate comparison:
where to_char(to_date(mmyy, 'MMYY'), 'YYYY-MM') = to_char(sysdate, 'YYYY-MM')
or, more simply:
where mmyy = to_char(sysdate, 'MMYY')
You can convert the current date to a string and use string comparisons (which would allow you to use an index on your column):
SELECT *
FROM your_table
WHERE your_date_column = TO_CHAR( SYSDATE, 'MMYY' )
or you can convert the column to a date and compare it (which would not use an index on your column but could use a function-based index, if you created one):
SELECT *
FROM your_table
WHERE TO_DATE( your_date_column, 'MMYY' ) = TRUNC( SYSDATE, 'MM' )

uisng to_date function still get date format picture ends before converting entire input string error

I have the following code where I want to see if a date is less than a year ago:
select id
from mytable
where id= :p_id
and (to_date(trunc(sysdate), 'yyyy-mm-dd') - to_date(datewhen, 'yyyy-mm-dd')) < 365;
I keep getting the error:
ORA-01830: date format picture ends before converting entire input
string
Looking at other question with the same error on StackOverflow I see the solution usually is to use the to_date function which I am doing so I am unsure why this is occuring. The datewhen field is of type Date.
Do not use to_date() with the columnes of DATE data type. to_date() converts character string to a value of DATE data type. It makes no sense to convert the DATE to DATE. In a first step datewhen column of type DATE will be implicitly converted into a character data type by using the default date format (that's most probably not 'yyyy-mm-dd') and this is the culprit of the ORA-01830 error.
So your statement should look something like this:
select id from mytable where id = :p_id and (trunc(sysdate) - trunc(datewhen)) < 365;
I'd calculate the difference in the months or years instead of days:
... where months_between(sysdate, datewhen) < 12
If your datewhen column is char/varchar formatted as yyyy-mm-dd then you have to do the to_date conversion on datewhen, but not on SYSDATE: it's already a date and doesn't need to be converted.
To filter on a date within the past 365 days, compare it to SYSDATE - 365:
select id
from mytable
where id = :p_id
and to_date(datewhen, 'yyyy-mm-dd') > sysdate - 365;
But a year isn't always 365 days: on leap years it's 366 days. To get a one year ago value that's always correct, subtract an interval of one year from the current date:
select id
from mytable
where id = :p_id
and datewhen > sysdate - interval '1' year;
One more thing: the Oracle DATE type isn't just a date; it's a date and a time. SYSDATE returns the current date and time. Try this query:
select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;
Unless you run this at exactly midnight you'll see a time component as well.
Say your query runs on 2 September 2017 at 10 AM and you're looking for a date within the past year. You'd expect to get the date 3 September 2016, but you wouldn't because at 10 AM SYSDATE is 3 September 2016 at 10:00:00. That's greater than the plain date 3 September 2016, which is 3 September 2016 at 0:00:00, so records with a datewhen of `2016-09-03' won't be included.
To ignore the time component of an Oracle DATE value, use TRUNC. Your final query should look something like this:
select id
from mytable
where id = :p_id
and datewhen > trunc(sysdate) - interval '1' year;
you use TO_DATE function when the value in character format
Syntax
The syntax for the TO_DATE function in Oracle/PLSQL is:
TO_DATE( string1 [, format_mask] [, nls_language] )

YYYYMMDD to YYYYMM in oracle

I have a column with DATE datatype in a table.
I am trying to retrieve the column values in YYYYMM format. My select query looks like below
select *
from tablename
where date column = to_char(to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
I am getting below exception.
ORA-01847: day of month must be between 1 and last day of month
Appreciate any input on this.
I think the simplest method is:
where to_char(datecolumn, 'YYYYMM') = '400012'
Or, if you prefer:
where to_char(datecolumn, 'YYYYMM') = to_char(to_date('12/31/4000', 'MM/DD/YYYY'), 'YYYYMM');
Syntax-wise, the right hand date (to the right of the equals) is OK. But you are doing a character comparison, not a date comparison.
This works for me in multiple databases:
select to_char (to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM')
from dual;
Even though your column is named DATE_COLUMN, you are comparing based on characters in the query.
So, try this instead - this compares based on dates (NOT a character comparison) and truncates off the hour, minute, ETC. so you are only comparing the DAY:
select * from DATE_TAB
where TRUNC(DATE1, 'DDD') = TRUNC(to_date('12/31/4000','MM/DD/YYYY'),'DDD');
NOTE: The DATE1 field above is a DATE field. If you're DATE_COLUMN is not a DATE field, you must
convert it to a DATE datatype first (using TO_DATE, ETC.)
Assuming that "date_column" is actually a date, and that you have an index on date_column, you can do something like this to return the data quickly (without truncating dates in all rows to do a comparison):
with dat as (
select level as id, sysdate - (level*10) as date_column
from dual
connect by level <= 100
)
select id, date_column
from dat
where date_column between to_date('11/1/2013', 'MM/DD/YYYY') and last_day(to_date('11/2013 23:59:59', 'MM/YYYY HH24:MI:SS'))
Here I just dummy up some data with dates going back a few years. This example picks all rows that have a date in the month of November 2013.
If your date_column's data-type is DATE, then use
select *
from tablename
where TO_CHAR(date_column,'YYYYMM') = to_char (to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
If your date_column's data-type is VARCHAR, then use:
select *
from tablename
where date_column = to_char (to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
I somehow feel your error is because you have a space between date and column as
"date column". If the field name in the table is "COLUMN", then just removing the word "DATE" from your original query would suffice, as:
select *
from tablename
where column = to_char(to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
If your column (YYYYMMDD) is in number format, the simplest way to get YYYYMM would be
select floor(DATE/100)
from tablename;

How to retrieve the records based on a date from oracle database

I have a table with date column in it. I need to fetch the records from it based on
the given date.
Currently when i used the query:
select * from workingemployee_data where created_date like '20-Jan-2012'
I am getting those records which have created_date on 20-Jan-2012
But i want to get the records those were created 10 days earlier to a given
date (i.e) 20-Jan-2012.
Please suggest me on this.
This gives all records between today and 10 days ago:
SELECT *
FROM workingemployee
WHERE created_date BETWEEN sysdate - INTERVAL '10' DAY
AND sysdate
This gives all records entered exactly 10 days ago:
SELECT *
FROM workingemployee
WHERE created_date = sysdate - INTERVAL '10' DAY
Replace sysdate with exact date if you want.
Why do you use like and not = ?
Assuming that created_date is of type DATE, it's bad practice to rely on implicit conversion according to NLS_DATE_FORMAT (this is what happens when you compare a date and a string)
dd-mon-yyyy isn't a good format for querying since it deffers according to NLS_LANGUAGE better use mm for months numbers
So, either use #mvp's answer or do something like this:
SELECT *
FROM workingemployee
WHERE trunc(created_date) = to_date('20-01-2013', 'dd-mm-yyyy') - 10
SELECT *
FROM workingemployee
WHERE created_date > sysdate - INTERVAL '10' DAY;