Let's say I have a table like this:
Event (eventID, StartDateTime, EndDateTime)
StartDateTime is datetime datatype
EndDateTime is datetime datatype
Now sample data could be like so:
EventID StartDateTime EndDateTime
-----------------------------------------------------------
1 2014-02-21 00:00:00.000 2014-02-23 23:59:59.000
2 2014-02-22 00:00:00.000 2014-02-24 23:59:59.000
I want to search what events are happening at 2014-02-23 00:00:00.000
SELECT
*
FROM
Event
WHERE
(StartDateTime <= '2/23/2013 00:00:00 AM')
OR (EndDateTime >= '2/23/2013 00:00:00 AM')
I have tried the above code but it doesn't return correct result.
Am I missing something? Can you tell me what I am missing?
You don't want OR, you want AND. You want events that started before or on the date you specified, and that end after the date you specified:
SELECT
*
FROM
Event
WHERE
StartDateTime <= '20130223'
AND
EndDateTime > '20130223'
Also, I'd seriously recommend that you start storing these date ranges as a semi-open interval, with an exclusive end date, if the time portion is important. It's a lot easier to compute exclusive end points, that read more cleanly:
INSERT INTO Event(EventID,StartDateTime,EndDateTime) values
(1,'2014-02-21T00:00:00.000','2014-02-24T00:00:00.000'),
(2,'2014-02-22T00:00:00.000','2014-02-25T00:00:00.000')
Which has the advantage that it's not (arbitrarily) excluding the last minute of the day, as your current ranges do.
use this query
SELECT * FROM Event
WHERE '2014-02-23 00:00:00.000' BETWEEN StartDateTime and EndDateTime
did you try BETWEEN?
DECLARE #EventTime DATETIME
SET #EventTime = '20140223 00:00:00'
SELECT *
FROM EVENT
WHERE #EventTime BETWEEN StartDateTime AND EndDateTime
Use Between operator in WHERE clause . It specifies a range to test.
Note BETWEEN operator is inclusive of boundary cases.
BETWEEN returns TRUE if the value of test_expression is greater than or equal to the value of begin_expression and less than or equal to the value of end_expression.
Related
I have a datetime field and would like to select the records having a date less than or equal to today but ignoring the time part of it.
My datetime field is as below:
2019-05-17 13:31:15.900, 2019-05-16 13:32:17.277, 2019-05-24 15:20:03.823
I would like to fetch only the rows with datetime 2019-05-17 13:31:15.900 and 2019-05-16 13:32:17.277 ignoring the time part.
Any idea of how to do that in sql server?
Simply, just cast both, your column and todays date to DATE:
SELECT * FROM MyTable
WHERE CAST(dt AS DATE) <= CAST(GETDATE() AS DATE)
You may try casting GETDATE() to a date type, to compare against tomorrow at midnight:
SELECT *
FROM yourTable
WHERE dt < CAST(DATEADD(day, 1, GETDATE()) AS date);
-- earlier than tomorrow at midnight
The date when this answer was written was 17-June-2019, so the above query would return any record whose datetime is strictly less than 18-June-2019 at midnight. The latest record would therefore be '2019-06-17 23:59:59'.
How to split this TimeStamp column without changing data format?
I have a column TimeStamp which is in datetime format, and I just want to keep the date part (in datetime format).
I tried to use
CONVERT(DATE, "TimeStamp")
it shows only the date part, but the format is nvarchar(10).
SQL Code:
SELECT
"TimeStamp",
CONVERT(DATE, "TimeStamp") AS Date
My expected result:
TimeStamp (datetime) Date (datatype: datetime)
------------------------------------------------------
2017-03-10 07:30:25 2017-03-10
2017-03-10 07:30:28 2017-03-10
2017-03-10 07:31:30 2017-03-10
2017-03-10 07:31:39 2017-03-10
Tysss I have made a demo for you please try this, Here I have used GETDATE() for return current date with a timestamp where you have to pass your column name as you showed in the question which is TimeStamp.
SOLUTION 1
SELECT CAST(CONVERT(VARCHAR,GETDATE(),110) AS DATE) AS DATE
OUTPUT
2019-05-17
SOLUTION 2
SELECT CAST(CONVERT(VARCHAR,GETDATE(),110) AS DATETIME) AS DATE
OUTPUT
2019-05-17 00:00:00.000
I think you need the only date from TimeStamp so, you need to change the datatype DATE else if you will keep your datatype DATETIME then it will return date something like 2019-05-17 00:00:00.000
select GETDATE() as TimeStamp,
convert(date, getdate()) as date
SELECT CONVERT(date, getdate());
I have two datetime columns in a DB table: #Start and #End.
Both columns contain the date and time, for example:
#Start: 2018-10-01 19:00:00
#End: 2018-10-10 23:59:00
I want to know if the current date is exactly between both datetimes considering the dates and the times.
So, 2018-10-08 16:37 and 2018-10-10 23:59:00 would match this range
and 2018-10-11 00:00:00 would not.
(In this case this date is one minute later than the End date, so it is not between my datetime range).
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN Start AND End
I don't use GETDATE() in real code, I use an argument. The problem is that current date argument may contain seconds and milliseconds like 23:59:59.123. My code treats such date as not conforming given range. But I don't care about s/ms.
Is there a workaround?
Update:
The precision I want to achieve is in minutes. So I do not even need to take in account the seconds nor the milliseconds. The date time format I would be working on would be 'yyyy-MM-dd hh-mm' but I do not know how to use the BETWEEN clause converting the Start and End to the shown format so I can compare the dates.
You would seem to want this logic:
WHERE GETDATE() >= Start
AND GETDATE() < DATEADD(minute, 1, End)
Assuming that the time part of End is 23:59:00 it covers all possible values between 23:59:00 and 23:59:59.999...999.
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN '2018-10-01 19:00:00' AND '2018-10-10 23:59:00'
TRY
SELECT Id FROM Table1 WHERE
CONVERT(varchar(16),GETDATE(),121) BETWEEN
CONVERT(varchar(16),[Start], 121)
AND
CONVERT(varchar(16),[END],121);
Example of rounding without strings
DECLARE #GetDateMinutes as datetime2;
DECLARE #X as datetime2 = getdate();
--round to minutes, could be made into a function
SET #GetDateMinutes = dateadd(minute,datepart(minute,#x),dateadd(hour, datepart(hour,#x),cast(CAST(#x as date) as datetime2)))
select #x, #GetDateMinutes
Truncate the seconds using the technique described here to avoid all string conversions, then just do your comparison. Here's a fully contained example that uses cross apply and values to encapsulate the truncation logic for start and end:
-- truncate minutes from current date time
declare #currentDateTime datetime2(0) = DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), N'2018-10-01 23:58:32.912')), 0);
select #currentDateTime as CurrentDateTime
, a.*
from (values -- create a table of dummy values
(Convert(datetime2(3), N'2018-10-01 19:48:14.735'), Convert(datetime2(3), N'2018-10-10 02:00:00.000'))
, (Convert(datetime2(3), N'2018-10-01 22:43:19.532'), Convert(datetime2(3), N'2018-11-01 12:17:26.663'))
) as a (StartDateTime, EndDateTime)
cross apply (values(
-- truncate minutes from start date time
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.StartDateTime)), 0)
-- truncate minutes from end date time
, DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.EndDateTime)), 0)
)) as b (StartDateTimeWithoutSeconds, EndDateTimeWithoutSeconds)
where #currentDateTime between b.StartDateTimeWithoutSeconds and b.EndDateTimeWithoutSeconds;
Your data appears to already have the s/ms truncated from start and end but figured I'd apply the same logic to all values involved just to be consistent. Here's the formula for stripping s/ms without all the "noise" from the example:
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), <SomeDateTime>)), 0)
I am trying to get the accesstime between two times.
Example
accesstime starttime endtime
23:00 22:00 00:00:00
My query look like this
select accesstime
from myTable
where accesstime between '22:00:00'and '00:00:00'
When I run the query I get no results
Why?
Because the time goes from 00:00:00 to 23:59:59
so, 22:00 is bigger than 00:00:00 in the same day
edit: This considering as a DateTime. If they are Varchar, you have the same problem, because 22:00 as a Varchar is bigger than 00:00:00
Information about BETWEEN:
BETWEEN returns TRUE if the value of test_expression is greater than
or equal to the value of begin_expression and less than or equal to
the value of end_expression.
In your table, accesstime '23:00' (test expression) is greater than '22:00:00' (begin expression) but is not less than '00:00:00' (end expression) and so it returns false.
In order to see results, change your query to:
select accesstime from myTable
where accesstime between '00:00:00' and '23:00:01'
i think you can Convert times to datetime and by dateadd function add ONE day to time '00:00:00' and then it works true.
the sample code is here:
CREATE table EX_Time (accesstime nvarchar(100),starttime nvarchar(100),endtime nvarchar(100))
INSERT INTO EX_Time(accesstime,starttime,endtime)
VALUES (N'23:00:00',N'22:00:00',N'00:00:00')
select *
FROM Ex_Time
Where convert(datetime,accesstime) BETWEEN convert(datetime,'22:00:00')
AND dateadd(day,1,convert(datetime,'00:00:00'))
If I run a query with a between clause, it seems to exclude the ending value.
For example:
select * from person where dob between '2011-01-01' and '2011-01-31'
This gets all results with dob from '2011-01-01' till '2011-01-30'; skipping records where dob is '2011-01-31'. Can anyone explain why this query behaves this way, and how I could modify it to include records where dob is '2011-01-31'? (without adding 1 to the ending date because its been selected by the users.)
From the MySQL-manual:
This is equivalent to the expression
(min <= expr AND expr <= max)
The field dob probably has a time component.
To truncate it out:
select * from person
where CAST(dob AS DATE) between '2011-01-01' and '2011-01-31'
The problem is that 2011-01-31 really is 2011-01-31 00:00:00. That is the beginning of the day. Everything during the day is not included.
select * from person where dob between '2011-01-01 00:00:00' and '2011-01-31 23:59:59'
Is the field you are referencing in your query a Date type or a DateTime type?
A common cause of the behavior you describe is when you use a DateTime type where you really should be using a Date type. That is, unless you really need to know what time someone was born, just use the Date type.
The reason the final day is not being included in your results is the way that the query is assuming the time portion of the dates that you did not specify in your query.
That is: Your query is being interpreted as up to Midnight between 2011-01-30 and 2011-01-31, but the data may have a value sometime later in the day on 2011-01-31.
Suggestion: Change the field to the Date type if it is a DateTime type.
Hi this query works for me,
select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'
select * from person where DATE(dob) between '2011-01-01' and '2011-01-31'
Surprisingly such conversions are solutions to many problems in MySQL.
In MySql between the values are inclusive therefore when you give try to get between '2011-01-01' and '2011-01-31'
it will include from 2011-01-01 00:00:00 upto 2011-01-31 00:00:00
therefore nothing actually in 2011-01-31 since its time should go from 2011-01-31 00:00:00 ~ 2011-01-31 23:59:59
For the upper bound you can change to 2011-02-01 then it will get all data upto 2011-01-31 23:59:59
You can run the query as:
select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'
like others pointed out, if your dates are hardcoded.
On the other hand, if the date is in another table, you can add a day and subtract a second (if the dates are saved without the second/time), like:
select * from person JOIN some_table ... where dob between some_table.initial_date and (some_table.final_date + INTERVAL 1 DAY - INTERVAL 1 SECOND)
Avoid doing casts on the dob fiels (like in the accepted answer), because that can cause huge performance problems (like not being able to use an index in the dob field, assuming there is one). The execution plan may change from using index condition to using where if you make something like DATE(dob) or CAST(dob AS DATE), so be careful!
Set the upper date to date + 1 day, so in your case, set it to 2011-02-01.
select * from person where dob between '2011-01-01' and '2011-01-31' or dob like' 2011-01-31%'
Just add or <<column>> like "date%".