Oracle Date Issue in Where Clause - oracle

I am unable to get the date column to respect the where clause. Regardless what I do, it does not filter on date. I have tried all combinations of to_char and to_date in vain.
HAVING TO_CHAR(PAYMASTR.CHECK_DATE,'MM/DD/YYYY') > '01/01/2021'
I have also tried the code below with all combinations of to_char and to_date.
HAVING PAYMASTR.CHECK_DATE >= TO_DATE('01-01-2021 12:00:00 AM',
'MM-DD-YYYY HH:MM:SS AM')
The check_date of of type DATE.
Result set:
|COMPANY|EMPLOYEE|PAY_SUM_GRP|PAY_GRADE RATE|WAGE_AMOUNT|NET_PAY_AMT|GROSS_PAY|CHECK_DATE|
|-------|--------|-----------|--------------|-----------|-----------|---------|----------|
|2|5|REG 09|21.98|175.84|1459.96|2263.19|1/19/2007 12:00:00 AM|
|2|5|REG 09|21.98|175.84|1663.93|2589.43|1/5/2007 12:00:00 AM|

If CHECK_DATE column's datatype is DATE (should be! If it is VARCHAR2, you're doing it wrong!), then
having check_date > date '2021-01-01'
i.e. compare date to date literal.
Second code you posted is almost OK:
HAVING PAYMASTR.CHECK_DATE >= TO_DATE('01-01-2021 12:00:00 AM', 'MM-DD-YYYY HH:MI:SS AM')
--
MI for minutes; MM is for month

I found this article on code project that did the trick for me. I was struggling really hard to get the query to respect the date parameter in the queru. Setting the session to NLS_DATE_FORMAT worked. Not sure what other implications it may have. Will have to talk to the DBA.
Code Project

It's all about how Oracle stores and works with date DATATYPE
The date has seven components
Century, year, month, day, hour, minute, seconds
and all these components take seven bytes of storage.
Whenever you fetch a Date column from a table, the date value is formatted in a more readable form and this format is set in the nls_date_format parameter.
I am assuming you are grouping by CHECK_DATE otherwise you need to add this date filter with the WHERE clause.
So first check the datatype of your column CHECK_DATE
If it is date then
HAVING CHECK_DATE >= TO_DATE('01-01-2021', 'MM-DD-YYYY')
You don't have to provide hours, minutes, and seconds if omitted hours are rounded to 12 AM or 00 if the 24-hour format is used;
Or if you want to have hours as well then you used MM instead of MI for minutes.
HAVING CHECK_DATE >= TO_DATE('01-01-2021 00:00:00', 'MM-DD-YYYY HH24:MI:SS')
And this does not make sense
HAVING TO_CHAR(PAYMASTR.CHECK_DATE,'MM/DD/YYYY') > '01/01/2021'
You want to compare dates not characters and to_char will provide you a character string that has no sense of comparing with another string '01/01/2021'.
So if you are not grouping by CHECK_DATE user filter condition with WHERE clause
or check the datatype of CHECK_DATE if it is not DATE change it to DATE.

Related

Convert epoch to date in Oracle

Was wondering if anyone could help with precision time conversion.
Sample: 1501646399999 which is GMT: Wednesday, August 2, 2017 3:59:59.999 AM
I used the below query, but it always rounds off to 02-AUG-17 04:00:00. Can anyone please guide me
select TO_TIMESTAMP('1970-01-01 00:00:00.000', 'YYYY-MM-DD hh24:mi:SS.FF3') + ((1/86400000) * 1501646399999)
from dual;
The problem is that you're adding a number to your fixed timestamp, which is causing that timestamp to be implicitly converted to a date - which doesn't have sub-second precision.
If you add an interval instead then it stays as a timestamp:
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF3';
select TO_TIMESTAMP('1970-01-01 00:00:00.000', 'YYYY-MM-DD hh24:mi:SS.FF3')
+ numtodsinterval(1501646399999/1000, 'SECOND')
from dual;
TO_TIMESTAMP('1970-01-0
-----------------------
2017-08-02 03:59:59.999
Incidentally, you could slightly simplify your query with a timestamp literal:
select TIMESTAMP '1970-01-01 00:00:00' + numtodsinterval(...)
You may also want to check if you should be declaring that timestamp as being UTC, and converting back to local time zone after adding the epoch value; or leaving it explicitly as UTC but as a timestamp with time zone value. It depends exactly what that number is supposed to represent. (You said it's GMT/UTC, but still...)

How do I update the time in oracle sql?

I need a query to update a time in an appointment date by keeping the date but changing the time.
For example
10-Feb-2016 09:00:00
and i want to change it to 10-Feb-2016 10:00:00.
Update Appointment
set vdate = '10:00:00'
where vdate= '10-Feb-2016'
I get the "0 row has been updated'. Not sure if i'm missing something.
Thanks in advance.
You can use trunc() which sets the time part of a DATE (or TIMESTAMP) to 00:00:00, then add the 10 hours to it:
Update Appointment
set vdate = trunc(vdate) + interval '10' hour
where trunc(vdate) = DATE '2016-02-10'
This would change all rows that have a date 2016-02-10. If you only want to do that for those that are at 09:00 (ignoring the minutes and seconds) then just add one hour to those rows
Update Appointment
set vdate = trunc(vdate) + interval '1' hour
where trunc(vdate, 'hh24') = timestamp '2016-02-10 09:00:00'
trunc(vdate, 'hh24') will set the minutes and seconds of the date value to 00:00, so that the comparison with 2016-02-10 09:00:00 works properly.
Unrelated, but: do not rely on implicit data type conversion. '10-Feb-2016' is a string value, not a DATE literal. To specify a date either use an ANSI DATE literal (as I have done in the above statement) or use the to_date() function with a format mask to convert a string literal to a proper date value.
Your statement is subject to the evil implicit data type conversion and will fail if the SQL client running the statement uses a different NLS setting (it will fail on my computer for example)
If what you want to do is add an hour to a date, then you can do:
Update Appointment
set vdate = vdate + 1/24
where vdate = to_date('10/02/2016 09:00', 'dd/mm/yyyy hh24:mi');
since in Oracle, date differences are measured in number of days, and an hour is 1/24th of a day.
If what you want to do is specify an exact time (e.g. to 10:25:48), then you could do the following instead:
Update Appointment
set vdate = trunc(vdate) + 10/24 + 25/(24*60) + 48/(24*60*60)
where vdate = to_date('10/02/2016 09:00', 'dd/mm/yyyy hh24:mi');
Bear in mind that these updates will update all rows that have a date of 10th Feb 2016 at 9am. You'd need to change your query's where clause if you wanted to specify a more specific row or set of rows.
Try like this.
UPDATE MyTable
SET MyDate = DATEADD(HOUR, 4, CAST(CAST(MyDate AS DATE) AS DATETIME))
or
UPDATE MyTable
SET MyDate = DATEADD(HOUR, 4, CAST(FLOOR(CAST(MyDate AS FLOAT)) AS DATETIME))

extract week number from date postgres

I would like to extract the week number as:
2015-52
from a date formatted as:
2015-12-27
How can I perform this in postgres?
my weeks are calculated from monday to sunday.
To get the year and the week in a single character value, use to_char()
select to_char(current_date, 'IYYY-IW');
IW returns the year and the week number as defined in the ISO standard and IYYY returns the corresponding year (which might be the previous year).
If you need the year and the week number as numbers, use extract
select extract('isoyear' from current_date) as year,
extract('week' from current_date) as week;
I have done like this
extract(week from cast(current_date as date))
extract(year from cast(current_date as date))
As same with #a_horse_with_no_name, but be careful there is a little difference between extract('isoyear' from current_date) and extract('year' from current_date) if current_date is within week0 in new year(the last week(53) of last year), especially when you extract week as well.
For example:
The follow output is 2020 not 2021
select EXTRACT('isoyear' from to_timestamp('2021-01-02 17:37:27', 'YYYY-MM-DD hh24:mn:ss')) as year
The follow output is 2021
select EXTRACT('year' from to_timestamp('2021-01-02 17:37:27', 'YYYY-MM-DD hh24:mn:ss')) as year

Converting Time Interval to actual time in AM PM in Oracle

How can i convert the result of select statement of time interval field in respective time in Am/Pm format.
My Field is:
Interval Day(2) To Second(6)
I tried this:
select To_Char(Att_EntranceTime , 'HH:MI AM') From EMPLOYEEATTENDENCETABLE;
however this does not help me, i have also tried to add the basetime from systime to my interval field but that did not help.. can someone suggest me what to do?
Intervals can't be directly formatted, as you've discovered. You can add your interval to any date which has its time set to midnight, and then format the resulting date to show the time in your desired format. For example you could add it to today's date using trunc(sysdate):
to_char(trunc(sysdate) + my_interval, 'HH:MI AM')
You need to truncate it to set the time to midnight; otherwise the result will be your interval plus the current system time.
Or you can use any fixed date; here's an example with some dummy data set-up:
create table my_table (my_interval interval day(2) to second(6));
insert into my_table (my_interval) values (interval '0 12:34:56.78' day to second);
insert into my_table (my_interval) values (interval '99 01:02:03.456' day to second);
select my_interval, to_char(date '1970-01-01' + my_interval, 'HH:MI AM') as formatted
from my_table;
MY_INTERVAL FORMATTED
-------------------- ---------
+00 12:34:56.780000 12:34 PM
+99 01:02:03.456000 01:02 AM
The second value shows a potential problem. Your interval is defined to allow a two-digit day number, which means the interval can span anything less than 100 days. If you only extract the time portion you lose that information about the number of days. That may be what you want to happen though. If the interval is supposed to be representing a time of day, which wanting to show AM/PM implies - and it's unusual to store an actual time separate from its date - then having or allowing a number of days seems strange.

date conversion from DD/MM/YYYY HH:MM:SS to YYYYMM

i want to convert date to some other format.
Below is the example 04/03/10 09:00:50.000000000 AMto YYYYMM
Iam not able to get this , below is the query which i used to convert.
select to_char(to_date('04/03/10 09:00:50.000000000 AM','MM/DD/YYYY HH:MM:SS AM'),'YYYYMM') from table;
Iam getting exception as below
ORA-01810: format code appears twice
01810. 00000 - "format code appears twice"
Format Code for Minutes is MI, not MM. MM is for months.
You are using 2-digit year. Better to use RR for this. Even better use 4-digit year.
TO_DATE doesn't store fractional seconds. You need to use TO_TIMESTAMP and use the FF as format code.
So, your query would be
select to_char(to_timestamp('04/03/10 09:00:50.000000000 AM','MM/DD/RR HH:MI:SS.FF9 AM'),'YYYYMM')
from table;
To achieve your goal there are many issues to resolve ;)
Finally I made this like that:
select to_char(
to_timestamp('04/03/10 09:00:50.000000000 AM','MM/DD/YYYY HH:MI:SS.FF9 PM',
'nls_date_language = ENGLISH'),
'YYYYMM') from dual;

Resources