Oracle Date format - Strange behaviour - sql

I am writing a SQL query to retrieve data from a table between two dates. I give two inputs as shown. I convert the Date TO_CHAR(DD/MON/YYYY).
1. StartDate > 01/SEP/2009
EndDate < 01/OCT/2009
2. StartDate > 01/SEP/2009
EndDate < 1/OCT/2009
I don't get any result for the first input. When I change it to second one, I get the result.
What is the difference between 01/OCT/2009 & 1/OCT/2009 ?

when comparing dates you should always convert explicitely both sides of the operator to DATE datatype. Assuming StartDate and EndDate are both DATE datatype, this would work:
StartDate > to_date('01/SEP/2009', 'dd/MON/yyyy')
AND EndDate < to_date('01/OCT/2009', 'dd/MON/yyyy')
In your case however the result you get is consistent with VARCHAR comparison. You're comparing strings and it's VERY unlikely you will get the correct result (since months are NOT sorted alphabetically for instance).
If StartDate and EndDate are indeed VARCHAR you should convert them explicitely:
to_date(StartDate, 'dd/MON/yyyy') > to_date('01/SEP/2009', 'dd/MON/yyyy')
AND to_date(EndDate, 'dd/MON/yyyy') < to_date('01/OCT/2009', 'dd/MON/yyyy')
This is valid for all versions of Oracle.

Since I don't have an Oracle client available to verify my answer, it's not certain but: In Oracle, a single digit in the date string representing the day (D) is used to specify the day of week (Monday-Sunday), while 2 digits are used to specify the day of month (3 digits will represent the day in the year). Although you mentioned you're converting the string using what seems like the right way to do the interpretation, I think this could be the source of the problem (or at least could be an explanation to the difference..).

Related

Case expression - comparing dates

I am using the query below, if the deadline column (eh.Deadline) < today (getdate) then returns 1, else 0.
(case when he.Deadline < CONVERT(VARCHAR(10),GETDATE(),111) then 1 else 0 end) Deadline
Everything works fine, but I need to change it so that only the month and the year (not the day), are compared.
Example, if Deadline=10/01/2022 and today=11/01/2022
My query returns 1 (10/01/2022 < 11/01/2022)
I would like to compare only the month and the year - I would like it to return 0 as MM/YYYY it's the same (01/2022 = 01/2022)
EDIT:
The column he.Deadline has the following format: DD/MM/YYYY HH/MM and this could not be compared to GETDATE and to solve that I had to use CONVERT(VARCHAR(10),GETDATE(),111) instead of GETDATE
The above query is used for a dashboard I created, and I wouldn't want to change anything in the database.
All I want is to compare MM/YYYY instead of DD/MM/YYYY
Any ideas please?
Thank you very much!
you could do (case when EOMONTH(he.Deadline) < EOMONTH(GETDATE()) then 1 else 0 end) Deadline
set the date to last day of the month for both values before comparing them so only the month/year will matter in the end
edit: as long as Deadline is a date... if it isn't then you have to convert it to date before calling EOMONTH on it
Firstly you need to ensure you are comparing a datetime/date with a datetime/date not a string with a datetime, nor a string with a string, as the comparisons are different all different, and your desired result is comparing a date.
Then you should be storing your data in the correct datatype, which for a datetime is a datetime2. Storing your Deadline as a string is going to cause you pain and trouble for the life of the project and will perform badly.
However with the situation as it is, you need to first convert your Deadline column correctly into a date value, and then secondly one way to solve your actual problem is to compare to the first of the current month as follows:
select
-- Convert to a date datatype in order to be able to correctly compare to another date
convert(date,substring(he.Deadline,1,10),103) -- Ensure dd/mm/yyyy as opposed to mm/dd/yyyy
<
-- Calculate the first of the month and check whether the Deadline is before then
convert(date,dateadd(day, -1*(datepart(day,getdate())-1), getdate())) then 1 else 0 end Deadline
from (
values ('10/01/2022 12/30')
) he (Deadline)

How would SQL treat this date format?

I had a coworker run a data pull for me. The query was essentially
SELECT a, b, c
FROM table
WHERE date >= 06/01/2018
The where clause being June 1, 2018. The query ran but the date filter was incorrect (not ‘2018-06-01’) How did the server interpret the date used? Was any filtering applied?
If you specified exactly as you have shown it, without quotes, then it would probably have:
1) Calculated 6 divided by 1 divided by 2018 (resulting in an integer zero)
2) Converted the dates in your database to an int to match the compare data type, and done a compare.
I expect this returned all your rows.
You can use this (datediff) function.
SELECT a, b, c
FROM table
WHERE datediff(dateVar, from_unixtime(unix_timestamp('2018/06/01','yyyy/MM/dd'),'yyyy-MM-dd')) >= 0
from_unixtime(,'yyyy-MM-dd') converts string to a string of given format, e.g. '2018-06-01'
Alternatively, these are functions which can help:
date_sub(,xxx) subtracts xxx days from the string, and returns a new
string in the same format.
unix_timestamp(string date,string pattern) converts a
string of a given pattern to unix time stamp, ) if fail.
Reference: How to change date format in hive?
This condition is:
WHERE date >= 06/01/2018
The last part is a numerical expression which I believe is interpreted as (06 / 01) / 2018. Depending on the database, this would either be 0 or about 0.00297, depending on whether your database does integer division.
Now the database has a bit of a conundrum. It has a date on one side and a number on the other. The rules of type conversion say to convert the date to a number. Depending on the database, this could be an error or a valid number -- which would be larger than 0.
The correct way to express this is:
WHERE date >= '2018-06-01'
or:
WHERE date >= DATE '2018-06-01'

How to select records between two dates in Access? [duplicate]

This question already has an answer here:
Query to compare between date with time and date without time - python using access db
(1 answer)
Closed 4 years ago.
I need to select records with DateTime between two dates in an Access query. The problem is that when I'm execute this query:
select * from logs
where date_added >= CDate("01/10/2018")
AND date_added <= CDate("04/10/2018")
I need both border values but the result does not include the last day. Maybe because "04/10/2018" is converted to "04/10/2018 00:00:00" and this value is less than all date_added values of that day.
Can I convert date_added to date only?
Do you can add a day to your date?
AND date_added < DateAdd('d',1,CDate("04/10/2018"))
An alternative expression:
SELECT * FROM logs
WHERE DateValue(date_added) BETWEEN #01/10/2018# AND #4/10/2018#
Useful date functions and syntax:
Date literals can be delimited with # in both VBA code and SQL statements, so you don't have to call CDate() on string values. Examples: #10/6/2018 4:16 PM#, #1/1/2018#
Simple mathematical notation can be used to add and subtract whole days from a date value. Example: #10/6/2018# + 1 == #10/7/2018#
DateValue( val ) takes arguments of various formats and returns a date/time value with only the date portion. This answers your question Can I convert date_added to date only? It essentially returns the same date value with the time portion as 00:00:00.
Example: DateValue(#10/6/2018 4:16 PM#) == #10/6/2018#
DateAdd ( interval, number, date ) as already noted by Milad Aghamohammadi.
Within SQL only (not VBA), one can use the BETWEEN operator. It works with various data types that have a natural sort order, which includes date values.
Example ... WHERE [DateField] BETWEEN #1/1/2018# AND #4/1/2018#

Comparing a date and getting result of records having further dates

I am using sql for database connectivity. I am filtering records in database on date basis using sql query which consists of function convert(varchar(100),column name,106). I am comparing it with date having dd/MMM/yyyy format. As a result I get records of next all the dates.
Example: If I try to filter the table by 01/June/2017 then inspite of having records of that date, I get records of next all the dates. I am not able to get records of 01/June/2017.
I have used greater than or equal to expression.
It is better to convert it to this yyyymmdd number format and do the comparison as below:
select convert(int,convert(varchar(10),[your column],112))
20170529
Don't convert your dates into any format (=strings) when doing comparison. Always use the date (or datetime etc) format. That way you will be comparing the actual values, not string or numeric comparison. Here the problem is that format 106 is dd mon yyyy so it will never match your date because it's a string dd/MMM/yyyy but you will get any dates starting with 02 anyhow, for example 02/Jan/1990, because in alphabetical order that will come after your given date.

How to take differece between 2 dates of different format in SQL

I have a table with a LOAD_STRT_DTM colum. This is a date column and values are like this - 18-JUL-14 08.20.34.000000000 AM.
I want to find the data which came before 5 days.
My logic is -
Select * from Table where 24 *(To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY')) >120
The issue is -
Select (To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY')) from table
This query should give the NumberOfDays between two dates. But this is not working, I Doubt, the issue is because of the format of the LOAD_STRT_DTM colum.
Please let me know where i am doint it wrong.
If your column is DATE datatype everything is ok, just shoot an:
select * from table where LOAD_STRT_DTM > sysdate - 5;
No need to convert dates to DATE datatype.
(To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY'))
You don't have to convert a DATE into a DATE again. IT is already a DATE. You just need to use it for date calculations. You use TO_DATE to convert a STRING into a DATE.
For example, if you have a string value like '18-JUL-14', then you would need to convert it into date using TO_DATE. Since your column is DATE data type, you just need to use as it is.
This is a date column
I want to find the data which came before 5 days.
Simply use the filter predicate as:
WHERE load_strt_dtm > SYSDATE - 5;
NOTE : SYSDATE has both date and time elements, so it will filter based on the time too. If you want to use only the date part in the filter criteria, then you could use TRUNC. IT would truncate the time element.
I have answered a similar question, have a look at this https://stackoverflow.com/a/29005418/3989608
It looks like LOAD_STRT_DTM is a TIMESTAMP rather than a DATE, given the number of decimal points following the seconds. The only thing you have to be cautious about is that Oracle will convert a DATE to a TIMESTAMP implicitly where one of the operands is a TIMESTAMP. So the solution
WHERE load_strt_dtm > SYSDATE - 5
will work; as will
WHERE load_strt_dtm + 5 > SYSDATE
but the following will not:
WHERE SYSDATE - load_start_dtm < 5
the reason being that TIMESTAMP arithmetic produces an INTERVAL rather than a NUMBER.
first convert two dates to same format select datediff(dd,convert(varchar(20),'2015-01-01',112),convert(varchar(20),'01-10-2015',112))