Time based filtering using sql - sql

I need to select data based on date and time.I have two criteria.How to implement this.
1)select the data between 1-1-2013 and 1-10-2013 with time rage between 10 to 16
2)select the data between 1-1-2013 and 1-10-2013 with time range between 20 to 8 next morning
I implemented a code.Its only working for first criteria.Here is that code.
where date>='1-1-2013' AND date <'1-10-2013'
AND CAST(date AS TIME) between '10:00' and '16:00'
Here the date field in the table is datetime type.Pleases help to solve this

1)
WHERE Date Between '2013-01-01 10:00' AND '2013-10-01 16:00'
2)
WHERE Date Between '2013-01-01 20:00' AND '2013-10-01 08:00'

Try this:
DECLARE #tmp TABLE ( date DATETIME )
INSERT INTO #tmp
( date )
VALUES ( '2013-01-01 10:09:29' -- date - datetime
)
INSERT INTO #tmp
( date )
VALUES ( '2013-01-01 15:09:29' -- date - datetime
)
INSERT INTO #tmp
( date )
VALUES ( '2013-01-01 17:09:29' -- date - datetime
)
INSERT INTO #tmp
( date )
VALUES ( '2013-01-01 07:09:29' -- date - datetime
)
SELECT date
FROM #tmp AS t
WHERE CONVERT(DATE,date) >= CONVERT(DATE, '01-01-2013', 105)
AND CONVERT(DATE,date) <= CONVERT(DATE, '01-01-2013', 105)
AND CONVERT(TIME, date) BETWEEN CONVERT(TIME, '10:00')
AND CONVERT(TIME, '16:00')

did i understand correctly? i don't know..
try this
where date>='1-1-2013' AND date <'1-10-2013'
AND ((CAST(date AS TIME) between '10:00' and '16:00')
OR (CAST(date AS TIME) between '20:00' and '23:59')
OR (CAST(date AS TIME) between '00:00' and '08:00'))

Related

How to get records in specific time range when the time range is between two days

I'm trying to query a specific range of time:
i.e. 1/1/2021 - 1/31/2021
between 5:55AM - 5:00AM (next day) for all days in above date
You need to extract time portion from your timestamps (datetime type for T-SQL) and filter by them in addition to dates filter.
db<>fiddle here
declare
#dt_from datetime
, #dt_to datetime
, #tm_from time
, #tm_to time
, #dt datetime
;
select
#dt = convert(datetime, '2021-02-10 11:48:36', 120)
, #dt_from = convert(date, '2021-02-01', 23)
, #dt_to = convert(date, '2021-02-28', 23)
, #tm_from = convert(time, '05:55:00', 120)
, #tm_to = convert(time, '05:00:00', 120)
;
with a as (
select #dt as dt union all
select dateadd(hour, 20, #dt) union all
select dateadd(hour, -15, #dt) union all
select dateadd(hour, -6, #dt) union all
select dateadd(day, -30, #dt) union all
select convert(datetime, '2021-02-01 00:01:02', 120) union all
select convert(datetime, '2021-02-28 20:01:02', 120)
)
select *
from dt
/*Restrict dates*/
where dt >= #dt_from
and dt < dateadd(day, 1, #dt_to)
and (
/*Exclude time intervals between 05:00 and 05:55*/
cast(dt as time) <= #tm_to
or cast(dt as time) >= #tm_from
)
Or if you need only the cases when entire time frame falls into your dates (e.g. exclude times from 00:00 till 05:00 for start date and from 05:55 till 23:59:59 of end date):
select *
from dt
where dt between #dt_from and #dt_to
and (
/*Exclude time intervals between 05:00 and 05:55*/
cast(dt as time) <= #tm_to
or cast(dt as time) >= #tm_from
)
/*Exclude time intervals at boundary dates*/
and not(
(cast(dt as date) = #dt_from and cast(dt as time) <= #tm_to)
or (cast(dt as date) = #dt_to and cast(dt as time) >= #tm_from)
)

available room booking between two dates and and two times column sql server

i have four columns in my table.
STARTDATE STARTTIME ENDDATE ENDTIME ROOMCODE
2018-10-16 00:00:00.000 14:00 2018-10-16 00:00:00.000 18:00 CS0001
2018-10-16 00:00:00.000 18:00 2018-10-16 00:00:00.000 22:00 CS0001
i want to check booking is available or not
select CONFERENCE_ROOM from COR_CONFERENCE_BOOKING where
(cast(STARTDATE as datetime) + cast(START_TIME as time) >= cast('2018-10-16'
as datetime) + cast(DATEADD(MINUTE, 01, '14:00') as time)
and cast(STARTDATE as datetime) + cast(START_TIME as time) < cast('2018-10-
16' as datetime) + cast('18:00' as time))
or (cast(ENDDATE as datetime) + cast(END_TIME as time) >= cast('2018-10-16'
as datetime) + cast(DATEADD(MINUTE, 01, '14:00') as time)
and cast(ENDDATE as datetime) + cast(END_TIME as time) < cast('2018-10-16'
as datetime) + cast('18:00' as time))
and CONFERENCE_ROOM='CS0001'
problem is there i want to select the data if any data found on select query on passing date and time then room is booked otherwise its free.
please solve this query. Its too complicated for me.
Here's an example snippet for MS SQL Server.
I'm assuming that this is your target RDBMS because the example SQL uses that DATEADD function.
It'll only return the first record from the table variable.
Because the second record is out of the range.
declare #Table table (
ID INT PRIMARY KEY IDENTITY(1,1),
STARTDATE date,
STARTTIME time,
ENDDATE date,
ENDTIME time,
CONFERENCE_ROOM varchar(6)
);
insert into #Table (STARTDATE, STARTTIME, ENDDATE, ENDTIME, CONFERENCE_ROOM) values
('2018-10-16','14:00:00','2018-10-16','18:00:00','CS0001'),
('2018-10-16','18:00:00','2018-10-16','22:00:00','CS0001');
select ID, CONFERENCE_ROOM
from #Table t
where (CAST(STARTDATE AS DATETIME) + CAST(STARTTIME as DATETIME)) < (CAST(ENDDATE AS DATETIME) + CAST(ENDTIME as DATETIME))
and (CAST(STARTDATE AS DATETIME) + CAST(STARTTIME as DATETIME)) >= CAST('2018-10-16 14:00' AS DATETIME)
and (CAST(ENDDATE AS DATETIME) + CAST(ENDTIME as DATETIME)) <= CAST('2018-10-16 18:00' AS DATETIME)
and CONFERENCE_ROOM = 'CS0001';
If the STARTTIME & ENDTIME are VARCHAR's instead of TIME data types?
Then to avoid errors with trying to convert crap data, you could use TRY_CAST instead.
(If TRY_CAST is available on your version of MS SQL Server)
Because instead of an error a TRY_CAST would return NULL when the conversion fails.
Example:
select ID, CONFERENCE_ROOM
from #Table t
where STARTDATE = ENDDATE
and TRY_CAST(STARTTIME AS TIME) < TRY_CAST(ENDTIME AS TIME)
and STARTDATE = CAST('2018-10-16' AS DATE)
and TRY_CAST(STARTTIME AS TIME) >= CAST('14:00' AS TIME)
and TRY_CAST(ENDTIME AS TIME) <= CAST('18:00' AS TIME)
and CONFERENCE_ROOM = 'CS0001';

Getting Minutes by Hour for Date Range

I'm trying to write a SQL query (SQL Server) and part of it is determining the number of minutes per hour between two datetimes.
Example: 11/1/2018 09:05 - 11/1/2018 13:15
Hour 09: 55 minutes
Hour 10: 60 minutes
Hour 11: 60 minutes
Hour 12: 60 minutes
Hour 13: 15 minutes
These would then get put into a temp table and grouped by some other data which will then be used to calculate dollar amounts from these minutes.
Is there a way to accomplish something like this via SQL that isn't too slow or laborious?
Thanks!
I think a recursive CTE is possibly the best approach:
with cte as (
select startTime, endTime,
startTime_hour as hourStart,
(case when endTime < dateadd(hour, 1, startTime_hour) then endTime
else dateadd(hour, 1, startTime_hour)
end) as hourEnd
from (select t.*,
dateadd(hour, datediff(hour, 0, startTime), 0) as startTime_hour
from t
) t
union all
select startTime, endTime,
dateadd(hour, 1, hourStart) as hourStart,
(case when endTime < dateadd(hour, 2, hourStart) then endTime
else dateadd(hour, 2, hourStart)
end) as endHour
from cte
where hourEnd < endTime
)
select cte.hourStart,
(case when hourStart > startTime then datediff(minute, hourStart, hourEnd) else datediff(minute, startTime, hourEnd) end) as minutes
from cte
order by hourStart;
Here is a db<>fiddle.
Here is an alternative dynamic solution that you can work with two parameters (start/end dates) only:
create table #temp
([hour] int, [minutes] int)
declare #startTime datetime='11/1/2018 09:05'
declare #EndTime datetime='11/1/2018 13:15'
declare #tempStartTime datetime = #startTime
declare #nextTimeRounded datetime
declare #hourdiff int = DATEDIFF(HOUR,#startTime,#EndTime)
declare #counter int = DATEPART(HH,#startTime)
declare #limit int = #counter + #hourdiff + 1
while #counter < #limit
begin
insert into #temp ([hour]) values (#counter)
set #nextTimeRounded= (dateadd(hour,
1 + datepart(hour, #tempStartTime),
cast(convert(varchar(10),#tempStartTime, 112) as datetime))
)
if #nextTimeRounded > #EndTime
begin
set #nextTimeRounded = #EndTime
end
update #temp
set [minutes] = (case when DATEDIFF(MINUTE,#tempStartTime,#nextTimeRounded)=0 then 60 else DATEDIFF(MINUTE,#tempStartTime,#nextTimeRounded) end)
where [hour] = #counter
set #counter = #counter + 1
set #tempStartTime = DATEADD(MINUTE,DATEDIFF(MINUTE,#tempStartTime,#nextTimeRounded),#tempStartTime);
end
select * from #temp
Sample Data
Below, we pump four time ranges, with associated values, into a table. All time ranges are different, but the first two are 10h 30m apart. The second two are 9h 45m apart.
declare #times table (
startTime time,
endTime time,
val float
);
insert #times values
('2018-10-01 01:00:00', '2018-10-01 10:45:00', 7),
('2018-10-02 01:00:00', '2018-10-02 10:45:00', 8),
('2018-10-01 01:00:00', '2018-10-01 11:30:00', 1),
('2018-10-02 01:00:00', '2018-10-02 11:30:00', 3);
Solution
You can use the 'datediff' function to aggregate as you so desire. Use the modulo operator to convert your minutes into just the minutes that remain over when whole hours are discounted.
select ap.h,
ap.m,
sumVal = sum(val)
from #times
cross apply (select
h = datediff(hour, startTime, endTime),
m = datediff(minute, startTime, endTime) % 60
) ap
group by ap.h,
ap.m

How to differentiate two time timeperiod between two columns?

I wanna know how to differentiate a time period in a day between two columns like in time and out time?
DATEDIFF
DATEDIFF (datepart , startdate , enddate)
The datepart you have mentioend in your question is day. You can use any of day, d and dd
Sample
DECLARE #inTime DATETIME, #outTime DATETIME
SET #inTime = '2015-05-01 12:10:09'
SET #outTime = '2015-05-22 05:15:36'
SELECT DATEDIFF(DAY, #inTime, #outTime) AS timedifferentiate
In a query
SELECT ,inTime
,outTime
DATEDIFF(DAY, inTime, outTime) AS timedifferentiate
FROM yourTable
Just use a minus operator, and convert to time
SELECT
CONVERT(time, -- Note the time datatype range is 00:00:00.0000000 through 23:59:59.9999999
CONVERT(datetime, '2015-04-01 19:03') -- Out time
- CONVERT(datetime, '2015-04-01 09:02') -- In time
) TimeDiff

Check if a time is between two times (time DataType)

I have a table that has a column "Created" as a datetime.
I'm trying to query to check if the time for the Created value is between two times.
The Created datetime for the first row is '2013-07-01 00:00:00.000' (Midnight) and I'm trying to query for items with a time between 11PM and 7AM.
select *
from MyTable
where CAST(Created as time) between '23:00:00' and '06:59:59'
But no results are returned.
Do I need to convert my times to datetimes?
I suspect you want to check that it's after 11pm or before 7am:
select *
from MyTable
where CAST(Created as time) >= '23:00:00'
or CAST(Created as time) < '07:00:00'
select *
from MyTable
where CAST(Created as time) not between '07:00' and '22:59:59 997'
I had a very similar problem and want to share my solution
Given this table (all MySQL 5.6):
create table DailySchedule
(
id int auto_increment primary key,
start_time time not null,
stop_time time not null
);
Select all rows where a given time x (hh:mm:ss) is between start and stop time. Including the next day.
Note: replace NOW() with the any time x you like
SELECT id
FROM DailySchedule
WHERE
(start_time < stop_time AND NOW() BETWEEN start_time AND stop_time)
OR
(stop_time < start_time AND NOW() < start_time AND NOW() < stop_time)
OR
(stop_time < start_time AND NOW() > start_time)
Results
Given
id: 1, start_time: 10:00:00, stop_time: 15:00:00
id: 2, start_time: 22:00:00, stop_time: 12:00:00
Selected rows with NOW = 09:00:00: 2
Selected rows with NOW = 14:00:00: 1
Selected rows with NOW = 11:00:00: 1,2
Selected rows with NOW = 20:00:00: nothing
This should also work (even in SQL-Server 2005):
SELECT *
FROM dbo.MyTable
WHERE Created >= DATEADD(hh,23,DATEADD(day, DATEDIFF(day, 0, Created - 1), 0))
AND Created < DATEADD(hh,7,DATEADD(day, DATEDIFF(day, 0, Created), 0))
DEMO
WITH CTE as
(
SELECT CAST(ShiftStart AS DATETIME) AS ShiftStart,
CASE WHEN ShiftStart > ShiftEnd THEN CAST(ShiftEnd AS DATETIME) +1
ELSE CAST(ShiftEnd AS DATETIME) END AS ShiftEnd
FROM **TABLE_NAME**
)
SELECT * FROM CTE
WHERE
CAST('11:00:00' AS DATETIME) BETWEEN ShiftStart AND ShiftEnd -- Start of Shift
OR CAST('23:00:00' AS DATETIME) BETWEEN ShiftStart AND ShiftEnd -- End of Shift
Let us consider a table which stores the shift details
Please check the SQL queries to generate table and finding the schedule based on an input(time)
Declaring the Table variable
declare #MyShiftTable table(MyShift int,StartTime time,EndTime time)
Adding values to Table variable
insert into #MyShiftTable select 1,'01:17:40.3530000','02:17:40.3530000'
insert into #MyShiftTable select 2,'09:17:40.3530000','03:17:40.3530000'
insert into #MyShiftTable select 3,'10:17:40.3530000','18:17:40.3530000'
Creating another table variable with an additional field named "Flag"
declare #Temp table(MyShift int,StartTime time,EndTime time,Flag int)
Adding values to temporary table with swapping the start and end time
insert into #Temp select MyShift,case when (StartTime>EndTime) then EndTime else StartTime end,case when (StartTime>EndTime) then StartTime else EndTime end,case when (StartTime>EndTime) then 1 else 0 end from #MyShiftTable
Creating input variable to find the Shift
declare #time time=convert(time,'10:12:40.3530000')
Query to find the shift corresponding to the time supplied
select myShift from #Temp where (#time between StartTime and EndTime and
Flag=0) or (#time not between StartTime and EndTime and Flag=1)
select * from dbMaster oMaster where ((CAST(GETDATE() as time)) between (CAST(oMaster.DateFrom as time)) and
(CAST(oMaster.DateTo as time)))
Please check this
Should be AND instead of OR
select *
from MyTable
where CAST(Created as time) >= '23:00:00'
AND CAST(Created as time) < '07:00:00'