SQL query selecting between two dates - sql

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'

Related

DB2 date comparison

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';

TIMESTAMP To DATE in Oracle SQL

I have a column called Create_Date which has data in the format like 19-JUN-18 10.27.00.000000000 PM and data type is TIMESTAMP(6).
I am trying to look at date range like yesterday's date or between two dates in Create_Date without using TO_DATE(TO_CHAR(P.CREATE_DATE_TIME,'dd/mon/yy')) and entering the value as '19-JUN-18'.
I want to use Create_Date=SYSDATE-1 OR Create_Date=CURRENT_DATE-1 instead to filter on yesterdays date. Or Use Create_Date>=SYSDATE or Create_Date>=CURRENT_DATE to look at dates greater than or equal to today.
Can someone help?
You could use TRUNC:
SELECT *
FROM tab
WHERE Create_Date >= TRUNC(SYSDATE,'DD') -- -1
-- or between to dates (using date literals)
WHERE Create_Date >= DATE 'yyyy-mm-dd'
AND Create_Date < DATE 'yyyy-mm-dd'
As it's a timestamp I'd cast the truncated (to midnight) current date to a timestamp for clarity; Oracle will use an index on that column even if you leave it as a date, but it doesn't hurt to make it explicit:
where create_date >= cast(trunc(sysdate) as timestamp)
The trunc() function defaults to truncating to midnight; you can explicitly include 'DD' as a second argument if you prefer (for even more clarity, though some would see it as noise).
If you want a range, say yesterday:
where create_date >= cast(trunc(sysdate) - 1 as timestamp)
and create_date < cast(trunc(sysdate) as timestamp)
If you want to specify other dates then you can use timestamp literals, e.g. to see everything for May:
where create_date >= timestamp '2018-05-01 00:00:00'
and create_date < timestamp '2018-06-01 00:00:00'

Populating records using BETWEEN

A record has its date in 'yyyy.MM.dd' format (for example, 2018.05.02),
and I have made a query to populate certain records between a certain time frame.
SELECT * FROM tableA WHERE (BATCHDT '2018.01.01' AND '2018.05.01');
The query looks fine, at least to me, but does not work on my MSSQL.
Please help.
Just use ANSI standard formats:
SELECT *
FROM tableA
WHERE BATCHDT BETWEEN '2018-01-01' AND '2018-05-01';
No conversion should be necessary. I do not recommend using BETWEEN with dates, because they might have a time component. A safer method is:
SELECT *
FROM tableA
WHERE BATCHDT >= '2018-01-01' AND
BATCHDT < '2018-05-02';
try this.
In SQL a Date type is a Date type regardless of the format. Using it will mean casting the field against literals
SELECT * FROM tableA WHERE cast(BATCHDT as date) BETWEEN '2018-01-01' AND '2018-05-01'
--- 2018-jan-01 and 2018-May-01
You may need to convert your source field data into acceptable format for date conversion.
If your source data 'yyyy.MM.dd' format (for example, 2018.05.02)
then you can change it into format that acceptable for date conversion, for example 'YYYYMMDD', by remmoving the '.' character (so your date record become 20180502)
the query could be as follows
SELECT * FROM tableA WHERE cast(REPLACE(BATCHDT,'.','') as date) BETWEEN '20180101' AND '20180501'
by default in MSSQL server also recognize 'YYYYMMDD' format for conversion into date, so you also not required to cast it into date first
SELECT * FROM tableA WHERE REPLACE(BATCHDT,'.','') BETWEEN '20180101' AND '20180501'
I would suggest you to keep BATCHDT as DATE datatype to avoid confusion with time values, which will come with DATETIME.
Also, suggest you to use ISO 8601 standard for representing dates.
BETWEEN is a inclusive operator. So, below
BETWEEN '2018-01-01' AND '2018-05-01' will turn to be
BETWEEN '2018-01-01 00:00:00.000' AND '2018-05-01 00:00:00.000'
So, it will not return values which fall on date 2018-05-01. So, you have to apply below BETWEEN condition
BETWEEN '2018-01-01 00:00:00.000' AND '2018-05-01 23:59:59.997'
Instead of that, I would suggest you to go for DATE operator, which is very straight forward for BATCHDT.
BETWEEN '2018-01-01' AND '2018-05-01'

SQL "between" not inclusive

I have a query like this:
SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'
But this gives no results even though there is data on the 1st.
created_at looks like 2013-05-01 22:25:19, I suspect it has to do with the time? How could this be resolved?
It works just fine if I do larger date ranges, but it should (inclusive) work with a single date too.
It is inclusive. You are comparing datetimes to dates. The second date is interpreted as midnight when the day starts.
One way to fix this is:
SELECT *
FROM Cases
WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'
Another way to fix it is with explicit binary comparisons
SELECT *
FROM Cases
WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'
Aaron Bertrand has a long blog entry on dates (here), where he discusses this and other date issues.
It has been assumed that the second date reference in the BETWEEN syntax is magically considered to be the "end of the day" but this is untrue.
i.e. this was expected:
SELECT * FROM Cases
WHERE created_at BETWEEN the beginning of '2013-05-01' AND the end of '2013-05-01'
but what really happen is this:
SELECT * FROM Cases
WHERE created_at BETWEEN '2013-05-01 00:00:00+00000' AND '2013-05-01 00:00:00+00000'
Which becomes the equivalent of:
SELECT * FROM Cases WHERE created_at = '2013-05-01 00:00:00+00000'
The problem is one of perceptions/expectations about BETWEEN which does include BOTH the lower value and the upper values in the range, but does not magically make a date the "beginning of" or "the end of".
BETWEEN should be avoided when filtering by date ranges.
Always use the >= AND < instead
SELECT * FROM Cases
WHERE (created_at >= '20130501' AND created_at < '20130502')
the parentheses are optional here but can be important in more complex queries.
You need to do one of these two options:
Include the time component in your between condition: ... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59' (not recommended... see the last paragraph)
Use inequalities instead of between. Notice that then you'll have to add one day to the second value: ... where (created_at >= '2013-05-01' and created_at < '2013-05-02')
My personal preference is the second option. Also, Aaron Bertrand has a very clear explanation on why it should be used.
Just use the time stamp as date:
SELECT * FROM Cases WHERE date(created_at)='2013-05-01'
I find that the best solution to comparing a datetime field to a date field is the following:
DECLARE #StartDate DATE = '5/1/2013',
#EndDate DATE = '5/1/2013'
SELECT *
FROM cases
WHERE Datediff(day, created_at, #StartDate) <= 0
AND Datediff(day, created_at, #EndDate) >= 0
This is equivalent to an inclusive between statement as it includes both the start and end date as well as those that fall between.
cast(created_at as date)
That will work only in 2008 and newer versions of SQL Server
If you are using older version then use
convert(varchar, created_at, 101)
You can use the date() function which will extract the date from a datetime and give you the result as inclusive date:
SELECT * FROM Cases WHERE date(created_at)='2013-05-01' AND '2013-05-01'
your code
SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'
how SQL reading it
SELECT * FROM Cases WHERE '2013-05-01 22:25:19' BETWEEN '2013-05-01 00:00:00' AND '2013-05-01 00:00:00'
if you don't mention time while comparing DateTime and Date by default hours:minutes:seconds will be zero in your case dates are the same but if you compare time created_at is 22 hours ahead from your end date range
if the above is clear you fix this in many ways like putting ending hours in your end date eg BETWEEN '2013-05-01' AND ''2013-05-01 23:59:59''
OR
simply cast create_at as date like cast(created_at as date) after casting as date '2013-05-01 22:25:19' will be equal to '2013-05-01 00:00:00'
Dyamic date BETWEEN sql query
var startDate = '2019-08-22';
var Enddate = '2019-10-22'
let sql = "SELECT * FROM Cases WHERE created_at BETWEEN '?' AND '?'";
const users = await mysql.query( sql, [startDate, Enddate]);
Even though it is inclusive, as per Aaron Bertrand suggestion (read more about it here)
don't use BETWEEN for date/time ranges.
Apart from other good answers around here, one can also use DATEADD (to add a number of days to a given date) as follows
SELECT * FROM Cases WHERE created_at >= '2013-05-01' AND created_at < DATEADD(day, 1, '2013-05-01')

value not retriving in ms access query with date time

need to select the amount of given date which will be in between start date and end date
its working fine for me when i am using '2/27/2012' or '2/28/2012'
but for '2/29/2012' its not selecting the amount
select amount from tblPricePeriod where cdate(2/1/2012) <=cdate('2/29/2012 12:00:00 AM')
and cdate(2/29/2012) >= cdate('2/29/2012 12:00:00 AM')
I wonder if this query might be close to what you want.
PARAMETERS WhichDate DateTime;
SELECT amount
FROM tblPricePeriod
WHERE
[WhichDate] >= StartDate
AND [WhichDate] <= EndDate;
If you don't want to do it as a parameter query, but create the query with a literal date value instead, try it like this ...
SELECT amount
FROM tblPricePeriod
WHERE
#2012-02-29# >= StartDate
AND #2012-02-29# <= EndDate;
Another option would be to use a BETWEEN expression in the WHERE clause.
SELECT amount
FROM tblPricePeriod
WHERE #2012-02-29# BETWEEN StartDate AND EndDate;
These suggestions assume StartDate and EndDate are both Date/Time data type. If they are text data type, you can use that CDate() function to use their date equivalents in your query.
CDate(StartDate)
CDate(EndDate)
Also the situation can be more complicated if your StartDate and EndDate values include time components other than midnight. You could however use the DateValue() function to cast those Date/Time values to midnight on the same date.
DateValue(StartDate)
DateValue(EndDate)
or
DateValue(CDate(StartDate))
DateValue(CDate(EndDate))