Some of the dates in a date column have an incorrect year. How do I change the first two digits of the year?
For example:
select
ID,
to_char(END_DT,'yyyy-mm-dd hh:mi:ss') as dt
From DB
Would result:
ID dt
1 0207-08-10 12:00:00
2 0208-03-31 12:00:00
3 0200-11-10 12:00:00
I want the results to look like this:
ID dt
1 2007-08-10 12:00:00
2 2008-03-31 12:00:00
3 2000-11-10 12:00:00
If you just want to "get" the correct date, you can use something like
select
substr(to_char(END_DT,'yyyy'),2,1) ||
substr(to_char(END_DT,'yyyy'),1,1) ||
substr(to_char(END_DT,'yyyy'),3,2) ||'-'||
to_char(END_DT,'mm-dd hh:mi:ss')
as dt
From DB;
The following logic should undo the problem, if this is a consistent formatting issue:
select (case when left(to_char(END_DT, 'yyyy'), 2) = '02'
then '20'||substr(to_char(END_DT,'yyyy-mm-dd hh:mi:ss'), 3, 100)
else to_char(END_DT,'yyyy-mm-dd hh:mi:ss')
end) as BetterFormat
This assumes that the problem is that the first two digits are reversed, and that this did not happen previous to 2000.
However, I must emphasize, the data is incorrect in the database. The right thing to do is to fix the data in the database. Covering up the problem might be making things worse in the medium term.
Related
I have numbers like 42946 in a database column and i want to format it as a normal Date like dd/mm/yyyy.
I was searching a lot but i dont find anything usefull.
I tried to do TO_DATE(<date>,'J') but this doesn't work beacuse i think 42946 is the number of days between today and January 1 of 1900, and this method works only for dates that are between today and January 1 of 4712 BC.
I hope you can help me with this.
i think 42946 is the number of days between today and January 1 of 1900
You mean, number of days since 1st of January 1900?
If so, you don't have to do much - just add that value to date you specified and you'll get the result. Its (result's) datatype is DATE so you can display it any way you want, using the to_char function (or any other option you prefer):
SQL> select date '1900-01-01' + 42946 as result from dual;
RESULT
----------
01.08.2017
SQL>
Example of formatting it:
SQL> select to_char(date '1900-01-01' + 42946, 'dd-mon-yyyy', 'nls_date_language = english') as result from dual;
RESULT
-----------
01-aug-2017
SQL>
I have a oracle sql query to get me the dates from 18/05/2021 to '28/05/2021'.
For some reason the the value after slash is not read, as the values from month 4 is also outputed. I dont know where i am wrong. Please give a hand if you are able, thanks a lot for your time.
NOTE: the dates have been stored in the database with a varchar datatype.
SELECT datadate
FROM mytable
WHERE trailerid= '1' and datattime>'05:00:00' and datattime<'12:00:00'
AND datadate between '18/05/2021' and '28/05/2021'
GROUP BY datadate ORDER BY datadate;
Current output
DATADATE
----------------
18/05/2021
19/04/2021
19/05/2021
20/05/2021
21/04/2021
21/05/2021
22/04/2021
22/05/2021
23/04/2021
23/05/2021
24/04/2021
24/05/2021
25/04/2021
25/05/2021
26/04/2021
26/05/2021
27/04/2021
27/05/2021
28/04/2021
28/05/2021
That's what happens when people store date values as strings.
See if this helps:
AND to_date(datadate, 'dd/mm/yyyy') between to_date('18/05/2021', 'dd/mm/yyyy')
and to_date('28/05/2021', 'dd/mm/yyyy')
You don't have to start over, just move the data to a datetime column
ALTER TABLE t ADD x DATE;
UPDATE t SET x = to_date(concat(datadate,datatime), 'dd/mm/yyyyhh24:mi:ss'))
WHERE datadate in (SELECT to_char(to_date('1999-12-31', 'yyyy-mm-dd') + level, 'dd/mm/yyyy') FROM dual CONNECT BY level <= 10000)
That WH ERE clause should generate a list of valid dates from 2000 to about 2030 - if you have dates outside this range adjust accordingly
Should now be able to find invalid dates (they weren't part of the where clause and x should hence remain null) and fix manually:
SELECT * FROM t WHERE x is null
Then drop your datadate and datatime cols and rename x to datadatetime
Now queries like BETWEEN work properly, and if you need just the date part you can do TRUNC(x). (You can even TRUNC to other date parts like hours, to cut the minutes and seconds off, or week of year to round dates down to the start of the week etc)
If you need just the time you either do x - TRUNC(x) which gives a decimal number like 0.5 for 12 noon or 0.75 for 6pm, or you can TOCHAR depending on what you want to do. It would be better to do x -TRUNC(x) BETWEEN 9.0/24.0 AND 17.0/24.0 than doing a string compare
WHERE (internalagentname is not null or internalagentcode is not null)
and (source LIKE '%GETAWAY%' or source like '%VACATION%')
and initialbookingdate <= to_Date(to_char(sysdate-1,'MM/DD/YYYY'),
'MM/DD/YYYY')
and (ABS(total_revenue) + ABS(total_cost) + ABS(booking_adjustment))<>0
so, this is my final step query were I am pulling data from yesterdays date. unfortunately its reading this as sysdate - 1 (from current time) so that's why it has data from today current date as well, how can i change this so it only takes out data from 12 am and before? thanks
You should simply be using the logic:
initialbookingdate < trunc(sysdate - 1)
The problem is the <=. The current time has nothing to do with the issue, because there is no time component in the conversion back to a date. Nevertheless, your expression is way more complex than it needs to be.
Saying that you need data that belongs to "yesterday", have a look at this:
SQL> select
2 sysdate right_now,
3 trunc(sysdate) todays_midnight,
4 trunc(sysdate - 1) yesterdays_midnight
5 from dual;
RIGHT_NOW TODAYS_MIDNIGHT YESTERDAYS_MIDNIGHT
------------------- ------------------- -------------------
21.03.2018 21:31:46 21.03.2018 00:00:00 20.03.2018 00:00:00
SQL>
It means that one option is to select values whose initialbookingdate is between "yesterdays_midnignt" and "todays_midnight", i.e.
where initialbookingdate between trunc(sysdate - 1) and trunc(sysdate)
(note that BETWEEN is inclusive).
A simpler option, which would ruin index you might have on initialbookingdate (so - although simpler, use it with caution. On small data amount you wouldn't see problems, but when handling many rows - yes, you would) is
where trunc(initialbookingdate) = trunc(sysdate - 1)
try to use below code in your query condition,
ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY HH:MI:SS AM';
SELECT TRUNC(sysdate)-(.00019/24) date_
FROM dual;
DATE_
----------------------
03/21/2018 11:59:59 PM
I have a query to update some field on some condition.
Conditions
The time difference is not more than 1 hour and the date can be same.
select *
from Table
where user_cd = 'HARSHIT'
and to_char(sysdate, 'dd/mm/yyyy') = to_char(brth_dt, 'dd/mm/yyyy');
But one condition is also there like at night the user tries to update at 23:30 and after that the he tries next day at 00:15 so the difference is 45 min but the update must execute
select brth_dt from Table where user_cd = 'HARSHIT';
select sysdate from dual;
select brth_dt from Table
where user_cd = 'HARSHIT'
and sysdate-(1/24) < BRTH_DT;
Result of above query
BRTH_DT
25/02/2016 12:30:00
1 row selected.
SYSDATE
24/02/2016 16:7:58
1 row selected.
BRTH_DT
25/02/2016 12:30:00
1 row selected.
I see no reason to convert a date to a string ... if you need to check 2 dates are within an hour of each other, just do the math on the date, and compare :
select * from sir_people
where user_cd = 'HARSHIT'
and BRTH_DT BETWEEN sysdate-(1/24)
AND sysdate;
to_char on a date, for purposes of comparisons, is fundamentally flawed logic and should be avoided.
[edit] based on example provided: it appears you want to exclude future dates, and only include those dates between now, and an hour earlier.
query updated to accomodate that additional requirement.
to_char(col_name, 'yyyy-mm-dd hh24:mi:ss')
just use 24-hour format, I think that should do the work.
Simply translate required condition into sql:
"The time difference is not more than 1 hour and the date can be same."
select *
from Table
where user_cd = 'HARSHIT'
and abs(sysdate-brth_dt) <= 1/24
I have a field next_repay_date as varchar2(11).
I need to get the date after 2 days.
Suppose I am having next_repay_date as 25-Sep-2011 as varchar2(11), I should get a result as 27-Sep-2011
Please suggest a solution?
Dates should not be held in char fields - use a Date or datetime
Then add two days - which I think is DBMS sepcific
Step 1, use the correct type for dates, that is, type DATE.
Step 2, use yourdate + INTERVAL 2 DAY (mysql).
Since you are using Oracle this could be done as
SELECT to_date('25-Sep-2007', 'dd-MON-RRRR') + 2 from dual
Date arithmetic is really simply in Oracle, providing we have an actual DATE to work with. So the first step is to cast your column to a DATE datatype, and then you can add or subtract days from it.
SQL> select to_date('27-SEP-2011', 'DD-MON-YYYY') + 2
2 from dual
3 /
TO_DATE('
---------
29-SEP-11
SQL>