Select between two dates when there is overlapping - sql

I have these data in my view
ID event_start event_end
499 2021-07-13 00:00:00.000 2021-07-13 00:00:00.000
499 2021-07-15 00:00:00.000 2021-07-15 00:00:00.000
499 2021-07-14 05:00:00.000 2021-07-14 06:00:00.000
499 2021-07-14 02:00:00.000 2021-07-14 03:00:00.000
499 2021-07-14 07:00:00.000 2021-07-14 09:00:00.000
So I have parameters as #date_start and #date_end and would like to select like this:
DECLARE #date_start datetime2 = '2021-07-14 07:00', #date_end datetime2 = '2021-07-14 08:10'
Select ID, t1.event_start, t1.event_end from Table1
WHERE event_start >= #date_start AND event_end <= #date_end
AND ID=499
That will give me no returned result. But my goal is to get the last row.
499 2021-07-14 07:00:00.000 2021-07-14 09:00:00.000
since this row starts at 7 and finishes at 9 which will cover the #date_start and #date_end period. How could I do that?
Also if I changed #date_start and #date_end to this:
DECLARE #date_start datetime2 = '2021-07-14', #date_end datetime2 = '2021-07-14'
It should return
499 2021-07-14 05:00:00.000 2021-07-14 06:00:00.000
499 2021-07-14 02:00:00.000 2021-07-14 03:00:00.000
499 2021-07-14 07:00:00.000 2021-07-14 09:00:00.000
because all three row happened on the same day but just different time.
Thank you

It seems you actually want to check for any overlaps of the date ranges in the table with the date range specified in the parameters.
Assuming that it doesn't matter if two intervals butt-end each other (say 07:00-08:00 and 08:00-09:00), you need to do an interval check like this start1 < end2 AND end1 > start2
DECLARE #date_start datetime2 = '2021-07-14 07:00', #date_end datetime2 = '2021-07-14 08:10'
SELECT
ID,
t1.event_start,
t1.event_end
FROM Table1
WHERE event_start < #date_end AND event_end > #date_start
AND ID = 499;

First thing to bear in mind, are your datetimes in DATETIME type?
If so, let's check the first case.
1.To see whether a datetime/timestamp is contained in a range, we specify the following WHERE clause:
WHERE
event_start <= '2021-07-14 07:00:00' and
event_end >= '2021-07-14 08:10:00'
1. OUTPUT
id event_start event_end
--- ----------------------- -----------------------
499 2021-07-14 07:00:00.000 2021-07-14 09:00:00.000
In case your data is not in DATETIME/TIMESTAMP type, this might not work.
2.Here, you change the condition, since you want all the stuff that happened during a whole day. Therefore, the WHERE clause looks like this:
WHERE
event_start >= '2021-07-14' and
event_end < '2021-07-15'
2. OUTPUT
id event_start event_end
--- ----------------------- -----------------------
499 2021-07-14 05:00:00.000 2021-07-14 06:00:00.000
499 2021-07-14 02:00:00.000 2021-07-14 03:00:00.000
499 2021-07-14 07:00:00.000 2021-07-14 09:00:00.000
Hope it helped!

Related

Trying to convert a date field, it leads to errors while conversion

I am trying the below query and keep getting the error for ResCreation date, I used CAST thinking that Rescreation date might have some bad fields. Not sure what field is wrong.
SELECT TOP(5)
[PCode]
,[ADate]
,[DDate]
,[ResCreationDate]
,[CancelDate]
FROM
[ResDomain]
WHERE
CAST(ResCreationDate AS DATE) >= '2018-01-01'
The error that I am getting:
Msg 241, Level 16, State 1, Line 2
Conversion failed when converting date and/or time from character string.
That's the sample data output:
PCode ADate DDate ResCreationDate CancelDate
FL7112 2018-07-30 00:00:00 2018-08-03 00:00:00 2018-05-29 16:34:30 2018-07-25 12:35:00
MT2091 2018-05-03 00:00:00 2018-05-04 00:00:00 2018-05-02 21:58:27 NULL
2075 2018-03-31 00:00:00 2018-04-01 00:00:00 2018-04-01 00:18:40 NULL
2012 2018-07-07 00:00:00 2018-07-08 00:00:00 2018-06-16 17:38:29 2018-06-30 03:20:00
2587 2018-06-30 00:00:00 2018-07-01 00:00:00 2018-06-30 11:18:10 NULL
Not sure if I should try another datatype, I used '2018-01-01 00:00:00' too in the where clause, but didn't work.
Use try_cast():
SELECT TOP (5) [PCode], [ADate], [DDate], [ResCreationDate]
FROM [ResDomain]
WHERE TRY_CAST(ResCreationDate as Date) >= '2018-01-01';
Or, better yet, find the bad data and fix it!
SELECT ResCreationDate
FROM ResDomain
WHERE TRY_CONVERT(Date, ResCreationDate) IS NULL;

Merge two records date if ToDate equal second FromDate SQL Server?

Example data:
FK_EmployeeId FromDate ToDate DateDiff
20325 2016-06-24 00:00:00.000 2016-06-25 00:00:00.000 2
20325 2016-06-25 00:00:00.000 2016-06-26 00:00:00.000 2
20325 2016-06-26 00:00:00.000 2016-06-28 00:00:00.000 3
20325 2016-06-28 00:00:00.000 2016-06-29 00:00:00.000 2
20325 2016-06-29 00:00:00.000 2016-06-30 00:00:00.000 2
20325 2016-06-30 00:00:00.000 2016-07-01 00:00:00.000 2
20325 2016-07-01 00:00:00.000 2016-07-02 00:00:00.000 2
20325 2016-07-02 00:00:00.000 2016-07-03 00:00:00.000 2
20325 2016-07-03 00:00:00.000 2016-07-04 00:00:00.000 2
20325 2016-07-04 00:00:00.000 2016-07-05 00:00:00.000 2
And I would like to get the following output:
FK_EmployeeId FromDate ToDate DateDiff
20325 2016-06-24 00:00:00.000 2016-06-26 00:00:00.000 3
20325 2016-06-28 00:00:00.000 2016-07-05 00:00:00.000 8
I think you are trying to do something like the below using a windowing function to join the records to themselves to perform the date comparisons across 2 rows.
However as people have already suggested in the comments your sample data above contains all sequential dates so its not really clear how your expecting this to work. I've therefore excluded a middle value in the sample data to demonstrate the approach.
--TABLE JUST FOR EXAMPLE QUERY
DECLARE #SomeTable TABLE ([FK_EmployeeId] INT,[FromDate] DATETIME,[ToDate] DATETIME,[DateDiff] INT)
--YOUR SAMPLE DATA
INSERT INTO #SomeTable
([FK_EmployeeId],[FromDate],[ToDate],[DateDiff])
SELECT 20325,'2016-06-24 00:00:00.000','2016-06-25 00:00:00.000',2
UNION SELECT 20325,'2016-06-25 00:00:00.000','2016-06-26 00:00:00.000',2
UNION SELECT 20325,'2016-06-26 00:00:00.000','2016-06-28 00:00:00.000',3
UNION SELECT 20325,'2016-06-28 00:00:00.000','2016-06-29 00:00:00.000',2
UNION SELECT 20325,'2016-06-29 00:00:00.000','2016-06-30 00:00:00.000',2
--UNION SELECT 20325,'2016-06-30 00:00:00.000','2016-07-01 00:00:00.000',2 --<<
UNION SELECT 20325,'2016-07-01 00:00:00.000','2016-07-02 00:00:00.000',2
UNION SELECT 20325,'2016-07-02 00:00:00.000','2016-07-03 00:00:00.000',2
UNION SELECT 20325,'2016-07-03 00:00:00.000','2016-07-04 00:00:00.000',2
UNION SELECT 20325,'2016-07-04 00:00:00.000','2016-07-05 00:00:00.000',2
--THE POINT:
;WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY [FK_EmployeeId] ORDER BY [ToDate]) AS 'RowNo'
FROM
#SomeTable
)
SELECT
a.*,
DATEDIFF(DAY,a.[FromDate],b.[ToDate]) AS 'NewDiff'
FROM
cte a
JOIN cte b
ON a.[RowNo] + 1 = b.[RowNo]
WHERE
a.[ToDate] <> b.[FromDate]
A little more detail in the question next time please.

Getting last 24 hours from current time in sql

I am not sure why the dateadd function is not working here. I am trying to pull only the last 24 hours from current time but i see hours like 3-6 pm of today's date. the data type is datetime but i am not sure what is going on here.
select Name, location, myDate from myTable where myDate >= DATEADD(hh, -24, GETDATE())
when i run the query above the outcome will include this:
2015-03-05 15:00:00.000
2015-03-05 15:30:00.000
2015-03-05 16:00:00.000
2015-03-05 16:30:00.000
2015-03-05 17:00:00.000
2015-03-05 17:30:00.000
2015-03-05 18:00:00.000
2015-03-05 18:30:00.000
2015-03-05 19:00:00.000
2015-03-05 19:30:00.000
2015-03-05 20:00:00.000
2015-03-05 20:30:00.000
2015-03-05 21:00:00.000
2015-03-05 21:30:00.000
2015-03-05 22:00:00.000
2015-03-05 22:30:00.000
2015-03-05 23:00:00.000
2015-03-05 23:30:00.000
I was expecting not to see these hours at all.
Use BETWEEN, ie
select Name, location, myDate from myTable where myDate between DATEADD(hh, -24, GETDATE()) and GETDATE()
This myDate >= DATEADD(hh, -24, GETDATE()) gets you all records where myDate is greater than 24 hours ago, including records that have future dates(if they are correct to have future dates is another story...)

Unable to set a condition in SQL Server 2008 R2

I have the following data set in the test table:
create table test
(
columndate date,
columntime datetime
)
insert into test values('2014-01-01','22:00:00')
insert into test values('2014-01-02','06:00:00')
insert into test values('2014-01-03','23:00:00')
insert into test values('2014-01-04','05:00:00')
insert into test values('2014-02-01','10:00:00')
insert into test values('2014-02-01','13:00:00')
insert into test values('2014-02-01','15:00:00')
insert into test values('2014-02-01','05:00:00')
columndate columntime
------------------------------------
2014-01-01 1900-01-01 22:00:00.000
2014-01-02 1900-01-01 06:00:00.000
2014-01-03 1900-01-01 23:00:00.000
2014-01-04 1900-01-01 05:00:00.000
2014-02-01 1900-01-01 10:00:00.000
2014-02-01 1900-01-01 13:00:00.000
2014-02-01 1900-01-01 15:00:00.000
2014-02-01 1900-01-01 05:00:00.000
Now I want to show only night timing in the result for example:
columndate columntime
-----------------------------------
2014-01-01 1900-01-01 22:00:00.000
2014-01-02 1900-01-01 06:00:00.000
2014-01-03 1900-01-01 23:00:00.000
2014-01-04 1900-01-01 05:00:00.000
2014-02-01 1900-01-01 05:00:00.000
For which I am trying the following script:
select * from test
where columndate between '2014-01-01' and '2014-02-01'
and cast(columntime as time) between '06:00:00' and '23:00:00'
Note: I will not get the record of timing 05:00:00
But when I use the following script:
select * from test
where columndate between '2014-01-01' and '2014-02-01'
and cast(columntime as time) between '05:00:00' and '23:00:00'
Note: I will get expected result but I am getting record of timing 06:00:00 also which I don't want to show.
How can I fix it?
You were really close: instead of BETWEEN you need to use a pair of >= and <=, because you need times outside an interval:
select * from test
where columndate between '2014-01-01' and '2014-02-01'
and (cast(columntime as time) <= '05:00:00' OR cast(columntime as time) >= '23:00:00')
Demo.
Does this meet your needs??:
select * from test
where columndate between '2014-01-01' and '2014-02-01'
and cast(columntime as time) between '05:00:00' and '23:00:00' and columntime ! ='06:00:00'

Group By,Order by DateTime

I have nearly 15000 data rows with the first column containing date in the format:
2012-05-10 09:00:00.000
I need this data to be sorted by year then month, then day, then hour so for example:
2012-05-10 09:00:00.000
2012-05-10 10:00:00.000
2012-05-10 11:00:00.000
2012-05-10 12:00:00.000
2012-05-11 09:00:00.000
2012-05-11 10:00:00.000
2012-05-11 11:00:00.000
2012-05-11 12:00:00.000
2012-06-01 02:00:00.000
2012-06-01 03:00:00.000
2012-06-01 04:00:00.000
2012-06-01 05:00:00.000
Current SQL Query to do this is below:
SELECT MIN(Datetime)
GROUP BY DATEPART(M,jmusa_LOG1.DateTime),DATEPART(D,jmusa_LOG1.DateTime),DATEPART(HH,jmusa_LOG1.DateTime)
HAVING MIN(jmusa_LOG1.DateTime) NOT IN(SELECT DateTime FROM AverageRawData)
ORDER BY DATEPART(M,jmusa_LOG1.DateTime),DATEPART(D,jmusa_LOG1.DateTime),DATEPART(HH,jmusa_LOG1.DateTime)
You are describing a normal date sort, so you can just do:
select MyDate
from AverageRawData
order by MyDate
If you don't want duplicates, add DISTINCT like this:
select distinct MyDate
from AverageRawData
order by MyDate
If this does not meet your requirements, please provide sample data used to generate your output example.