I see somewhere in the sql code in Amazon redshift that ::date is used when comparing two dates. I am wondering is there any difference between these three lines of code:
start_date < '2016-01-01'
start_date < '2016-01-01'::date
start_date < date('2016-01-01')
The result is the same in all three cases.
Specifically:
start_date < '2016-01-01' is trying to compare a date with a varchar, but Amazon Redshift is smart enough to convert the varchar into a date format for comparison purposes.
start_date < '2016-01-01'::date is doing a proper comparison between two date fields. This would be equivalent to date '2016-01-01'.
start_date < date('2016-01-01') appears to also be comparing date fields, although that syntax isn't in the Date and Time Functions documentation.
A more useful example of using ::date is when comparing two timestamps, and you only wish to compare the date, for example:
select end::date - start::date as days FROM table
Related
sql table
here in the table above named carpooling contains a column name start_on which has date time as timestamp i have to write a query to select all the rows having date as 25-11-20 using to_char and to_date.
You write a timestamp literal like this:
timestamp '2020-11-25 00:00:00'
so the full filtering condition will be
where start_on >= timestamp '2020-11-25 00:00:00'
and start_on < timestamp '2020-11-26 00:00:00'
Note that dates and timestamps are different in Oracle, and dates include times down to the second (this is for historical reasons - originally there was only the date type, and timestamp was added much later).
Use the TRUNC function, along with date and interval literals:
SELECT *
FROM CARPOOLING
WHERE START_ON BETWEEN DATE '2020-11-25'
AND (DATE '2020-11-26' - INTERVAL '0.000001' SECOND)
You can simply use to_date, but it's recommended to remove the time when comparing the dates. Otherwise, rows having the same date, but a different time will not be selected. Removing the time can be done using TRUNC.
So you can do something like this:
SELECT * FROM carpooling
WHERE TRUNC(start_on) = TO_DATE('2020-11-25','yyyy.mm.dd');
If you don't want to check the 25th of November 2020, but another data, change the date to match your goal.
How should look Select date range when dates are in varchar2 dd/mm/yyyy?
When I use:
SELECT * FROM invoice
WHERE data_doc >= '01/07/2020'
AND data_doc <= '19/07/2020'
Returns values where data_doc is i.e. = 02/03/2020
When you compare strings (varchar2's in this case), you compare them lexicographically. One approach would be to convert those strings to actual dates:
SELECT *
FROM invoice
WHERE TO_DATE(data_doc, 'DD/MM/YYYY') >= TO_DATE('01/07/2020', 'DD/MM/YYYY') AND
TO_DATE(data_doc, 'DD/MM/YYYY') <= TO_DATE('19/07/2020', 'DD/MM/YYYY')
Use TO_DATE conversions everywhere
SELECT * FROM invoice
WHERE TO_DATE(data_doc,'DD/MM/YYYY') >= TO_DATE('01/07/2020','DD/MM/YYYY')
AND TO_DATE(data_doc,'DD/MM/YYYY') <= TO_DATE('19/07/2020','DD/MM/YYYY')
You (alas) need to convert the column to dates. The comparison can then be done directly to dates:
WHERE TO_DATE(data_doc, 'DD/MM/YYYY') >= DATE '2020-07-01' AND
TO_DATE(date_doc, 'DD/MM/YYYY') <= DATE '2020-07-17'
For performance, Oracle supports indexes on expressions. So, you can create an index on TO_DATE(data_doc, 'DD/MM/YYYY').
That said, you should fix your data model so dates are stored correctly as dates.
Because you are comparing dates in the same month -- and only for that reason -- you can adjust your comparison by requiring that the data be in the same month:
WHERE data_doc >= '01/07/2020' AND
data_doc <= '19/07/2020' AND
data_doc LIKE '__/07/2020'
I strongly recommend that you fix the data type, though.
I'm trying to query a DB2 database to find records between two date columns, START_DATE and END_DATE (dates are stored in YYYYMMDD format in DB). This is what I have but it's not working. Could anyone please help me fix this?
SELECT *
FROM TBDeals
WHERE TIMESTAMP_FORMAT(START_DATE, 'YYYYMMDD') >= '2020-03-01'
AND TIMESTAMP_FORMAT(END_DATE, 'YYYYMMDD') <= '2020-04-20';
Thank you
You are storing dates as strings, which is not a good practice. On the other hand, the format that you are using does allow proper sorting, so why not simply check the existing values against strings, like so?
where startdate >= '20200301' and end_date <= '20200420'
The upside of this approach is that it can take advantage of indexes on the string dates columns.
If the values are numbers, then:
where startdate >= 20200301 and end_date <= 20200420
It seems that your date range is backwards, try this version:
SELECT *
FROM TBDeals
WHERE
TIMESTAMP_FORMAT(START_DATE, 'YYYYMMDD') >= '2020-03-20' AND
TIMESTAMP_FORMAT(END_DATE, 'YYYYMMDD') <= '2020-04-01';
For instance, I have a datetime like this '2016-04-02 00:00:00' and another like this '2016-04-02 15:10:00'. I don't care about the time-part, I want them to match just by the date-part.
I have tried with date(), to_date, datepart, nothing works.
Do it like this:
where yourField >= the start of your date range
and yourField < the day after the end of your date range
Edit starts here:
While you could use trunc, as suggested by others, bear in mind that filtering on function results tends to be slow.
Truncating the date to day should do the trick. Documentation here:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions201.htm
For example
SELECT TRUNC(SYSDATE, 'DAY') FROM DUAL;
As others have said - there is no separate "date" data type in Oracle. A pure "date" is stored as a date with the time portion set to 00:00:00 (midnight at the beginning of the day), and TRUNC(date) will take any date and truncate the time to 00:00:00, so if you need to compare two dates you can write
where trunc(date_1) = trunc(date_2)
If your tables are very large and you need to do these comparisons often, this is not ideal, because wrapping column values within function calls (like date_1 within a TRUNC) prevents the use of an index you may have on the date_1 column. If you need to compare dates in two columns you may not have much of a choice, but if you compare to a fixed date (or something like SYSDATE) you may be better off with something like
where date_1 >= trunc(sysdate) and date_1 < trunc(sysdate) + 1
Here you are not using trunc on the column value, so if there's an index on the column, Oracle is free to use it - and trunc(sysdate) is computed only once, not for every single row. "+1" by the way means "add one day".
TO_DATE converts a string to a date; if you apply TO_DATE to a value that is already a legitimate date, you will get unexpected results because Oracle will first convert your true date to a string and then back to date again, and since these conversions require a date FORMAT for strings, and the formats Oracle assumes for conversion from date to string and from string to date may not match, .... you get the idea. As far as I know, DATE() (a FUNCTION) and DATEPART do not exist in Oracle; when you use a new language, keep Google close by and use it often.
If you input a date with no time component, for example TO_DATE('04-apr-2016, 'dd-mon-yyyy'), then the implicit time is 00:00:00 so you don't need to apply TRUNC() to it.
Good luck!
I want to select records between two dates - a startDate and endDate (they are date/time format in sql). I have the following sql query but it does not work, could someone tell me what I'm doing wrong?
SELECT *
FROM house
WHERE startDate >= '2012/02/22 00:00:00' AND endDate <= '2012-02-25 00:00:00'
I would suggest converting the dates to a datetime and comparing them as well as keeping the date standard and consistent. Something like:
"SELECT *
FROM house
WHERE DATE(startDate) >= DATE('2012-02-22 00:00:00')
AND DATE(endDate) <= DATE('2012-02-25 00:00:00')"
NOTE: I assumed your startDate and endDate were of the same format as the strings your provided.
Do you want all rows that startDate is '2012-02-22' or later and endDate is '2012-02-22' or previous? Then, use this:
SELECT *
FROM house
WHERE startDate >= '2012-02-22'
AND endDate < '2012-02-26' --- notice the `<`, not `<=`
--- and the `day+1`
When using dates with SQL products, better use this format in queries and statements: '20120222' or this (which I find easier to read: '2012-02-22'.
Using slashes like '2012/02/22' or any other order than Year-Month-Day is not recommended.
There's no need to include the time part. '2012-02-22 00:00:00' is the same as '2012-02-22'.
Using endDate <= '2012-02-25 00:00:00' means that any row with date 25nd of Feb. 2012 but time after midnight ('00:00:00') will not match the condition. If you want those rows, too, use endDate < '2012-02-26' instead.
You could use DATE(endDate) <= DATE('2012-02-25 00:00:00') or DATE(endDate) <= '2012-02-25' but these conditions are "un-sargable", so your queries will not be able to use an index on endDate.
There is the builtin STR_TO_DATE function in MySql that takes same format mask as date_format.
start_date >= str_to_date('2012/02/22 00:00:00','%Y/%m/%d %h:%i:%s)
I guess thats type casting issue the reason why it din work because the input you are matching in the where clause is different that is the column is of date or datetime type and you are matching with a manual string format either use to_char on the left side of where to match the format on the right side or use to_date() on right side.
SELECT *
FROM house
WHERE
to_char(startDate, 'YYYY/MM/DD
24hh:mm:ss')>=
'2012/02/22 00:00:00'
AND to_char(endDate,
'YYYY/MM/DD
24hh:mm:ss') <= '2012-02-25
00:00:00'