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';
Related
I have a table with a date column (DD/MM/YYYY hh:mm:ss) as follows:
02/09/2021 09:50:37
03/09/2021 09:20:27
02/09/2021 14:05:25
03/09/2021 12:50:28
02/09/2021 14:25:26
What's the most efficient way to filter by date?
Note: I tried with
select date
from table
where date = '02/09/2021'
However, this provides results that wrongly lack the time and only contain the date 02/09/2021.
For example, 02/09/2021 09:50:37 would not be returned.
A simple option is
select *
from your_table
where trunc(date_column) = date '2021-09-02'
If there's an index on date_column, it wouldn't be used in that case so performance might suffer so you'll have to either create a function-based index, or use a different where clause:
where date_column >= date '2021-09-02' and date_column < date '2021-03-03'
If you want to return every record that has some date column equal to some date regardless to the time part then you need this:
select date
from table
where trunc(date) = '02/09/2021'
please avoid naming columns date and tables table.
Here is a small demo
Use a date range:
SELECT date_column
FROM table_name
WHERE date_column >= DATE '2021-09-02'
AND date_column < DATE '2021-09-02' + INTERVAL '1' DAY;
This will enable Oracle to use an index on the date_column column.
If you filter using:
TRUNC(date_column) = DATE '2021-09-02' or
TO_CHAR(date_column, 'DD-MM-YYYY') = '02-09-2021'
Then Oracle will not use an index on the date_column and would need a separate function-based index on either TRUNC(date_column) or TO_CHAR(date_column, 'DD-MM-YYYY').
enter image description here
The datatype of DATEInvoice is VARCHAR
From the image above, if I want to select the information of the invoice from specific time let say from 1-12-2020 00:00:00 to 13-12-2020 23:59:00, how can I write? I have try many ways to write. For example,
SELECT * FROM INVOICE WHERE DATEINVOICE BETWEEN To_date('01-12-2020 00:00:00','dd-mm-yyyy HH24:MI:SS') AND To_date('13-12-2020 23:59:00','dd-mm-yyyy HH24:MI:SS')
**BUT THE RESULT I GET IS RETURN ZERO ROWS. Hope anyone can help me, I am having trouble on this.
First, you can simplify your logic to:
WHERE DATEINVOICE >= '2020-01-12' AND
DATEINVOICE < '2020-01-14'
In some databases, you should identify date constants with the (standard) DATE keyword:
WHERE DATEINVOICE >= DATE '2020-01-12' AND
DATEINVOICE < DATE '2020-01-14'
This assumes that DATEINVOICE is stored as a valid datetime/timestamp value in your database. If it is a string, then it has the wrong type. You should fix your data model. If someone else has created such a broken data model, then you can convert the value in the WHERE clause:
WHERE TO_DATE(DATEINVOICE, 'dd-mm-yyyy HH24:MI:SS') >= '2020-01-12' AND
TO_DATE(DATEINVOICE, 'dd-mm-yyyy HH24:MI:SS') < '2020-01-14'
However, the effort should really be on fixing the data model.
Can use Please try MySQL's DATE() function:
WHERE DATE(datetime) = '2009-10-20'
You could also try this:
WHERE datetime LIKE '2009-10-20%'
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 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
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'