SQL Server Split Day in 4 Blocks of 2 hours - sql

I have few records of tasks with StartTime and StopTime and I would like to split it in 4 records of 2 hours (8:30 - 10:30 / 10:30 - 12:30 / 13:00 - 15:00 / 15:00 - 17:00)
Typically, i would like to split this row :
From
Title StartTime StopTime
Task1 2013-11-12 09:00 2013-11-12 14:00
To
Title StartTime StopTime
Task1 2013-11-12 09:30 2013-11-12 10:30
Task1 2013-11-12 10:30 2013-11-12 12:30
Task1 2013-11-12 12:30 2013-11-12 14:00
Any suggestion is welcome, thanks.

Try this query:
SQLFiddle demo
select [TaskName],
CASE WHEN CONVERT(varchar,StartTime,108)<pStart
THEN floor(CAST(StartTime as float))+Cast(pStart as Datetime)
ELSE StartTime
END as StartTime,
CASE WHEN CONVERT(varchar,StopTime,108)>pEnd
THEN floor(CAST(StopTime as float))+Cast(pEnd as Datetime)
ELSE StopTime
END as StopTime
FROM T
JOIN
(
SELECT '08:30:00' as pStart, '10:30:00' as pEnd
UNION ALL
SELECT '10:30:00' as pStart, '12:30:00' as pEnd
UNION ALL
SELECT '13:00:00' as pStart, '15:00:00' as pEnd
UNION ALL
SELECT '15:00:00' as pStart, '17:00:00' as pEnd
) as DayParts
ON (CONVERT(varchar,StartTime,108)<=pEnd
AND
CONVERT(varchar,StopTime,108)>=pEnd
)
OR
(
CONVERT(varchar,StopTime,108)>=pStart
AND
CONVERT(varchar,StartTime,108)<=pStart
)
ORDER BY TaskName,StartTime

Related

Pivot with Date and time

I have this query for Employee's fingerprints
SELECT
bp.Name
vahruae_date date,
to_char(vahruae_timeofattendance, 'hh:mi') Time
FROM vahruae_hr_empattendancelog empl
INNER JOIN c_bpartner bp ON empl.vahruae_enroll_id = bp.enroll_id
And the value displays as follows
Name Date Time
-----------------------------------------
John 01-SEP-2022 1:00
John 01-SEP-2022 9:00
John 01-SEP-2022 13:00
John 01-SEP-2022 16:00
John 02-SEP-2022 1:00
John 02-SEP-2022 6:00
John 04-SEP-2022 5:00
. .
. .
John 31-SEP-2022 4:30
John 31-SEP-2022 7:00
Ali 01-SEP-2022 10:00
Ali 04-SEP-2022 5:00
. .
. .
I want to display all times in one date row, like this
Name Date Time1 Time2 Time3 Time4
-----------------------------------------------------------------------------------------------
John 01-SEP-2022 1:00 9:00 13:00 16:00
John 02-SEP-2022 1:00 6:00 (null) (null)
John 04-SEP-2022 5:00 (null) (null) (null)
John 31-SEP-2022 4:30 7:00 (null) (null)
Ali 01-SEP-2022 10:00 (null) (null) (null)
Ali 05-SEP-2022 5:00 (null) (null) (null)
I'm not very good with Pivot, but I know I cannot use a subquery inside the Pivot IN Clause.
How can I accomplish that?
Use the ROW_NUMBER analytic function to index the times within a sub-query and then PIVOT using that:
SELECT name,
dt,
time1,
time2,
time3,
time4
FROM (
SELECT empl.vahruae_enroll_id,
bp.Name,
vahruae_date AS dt,
to_char(vahruae_timeofattendance, 'hh:mi') AS Time,
ROW_NUMBER() OVER (
PARTITION BY empl.vahruae_enroll_id,
vahruae_date,
TRUNC(vahruae_timeofattendance)
ORDER BY vahruae_timeofattendance
) AS rn
FROM vahruae_hr_empattendancelog empl
INNER JOIN c_bpartner bp
ON empl.vahruae_enroll_id = bp.enroll_id
)
PIVOT (
MAX(time)
FOR rn IN (1 AS time1, 2 AS time2, 3 AS time3, 4 AS time4)
)
We need to number the hours by date and name using row_number() and then pivoting.
select *
from
(
select "Name" as "Name"
,to_char("Date", 'hh24:mi') as "Time"
,to_date(to_char("Date", 'DD-mon-YYYY')) as "Date"
,row_number() over(partition by "Name", to_char("Date", 'DD-mon-YYYY') order by to_char("Date", 'hh24:mi')) as rn
from t
) t
pivot(max("Time") for rn in('1' as Time1, '2' as Time2, '3' as Time3, '4' as Time4)) p
order by "Name" desc, "Date"
Name
Date
TIME1
TIME2
TIME3
TIME4
John
01-SEP-22
01:00
09:00
13:00
16:00
John
02-SEP-22
01:00
06:00
null
null
John
04-SEP-22
05:00
null
null
null
John
01-OCT-22
04:30
07:00
null
null
Ali
01-SEP-22
10:00
null
null
null
Ali
04-SEP-22
05:00
null
null
null
Fiddle

How to split the time range into multiple rows

I want to split the date/time ranges into multiple rows by hour in SQL Server but have some issues. My current dataset looks like this:
EmployeeCode StartDateTime EndDateTime
843578 2017-05-14 8:30 AM 2017-05-14 11:36 PM
587123 2017-05-14 22:00 PM 2017-05-15 01:28 AM
And I want something like this as my result table. Note that I want to treat a block less than an hour as one independent row as well. (For example 8:30AM - 9:00AM as one row.)
EmployeeCode StartDateTime EndDateTime
843578 2017-05-14 8:30 AM 2017-05-14 9:00 PM
843578 2017-05-14 9:00 AM 2017-05-14 10:00 AM
843578 2017-05-14 10:00 AM 2017-05-14 11:00 AM
843578 2017-05-14 11:00 AM 2017-05-14 11:36 AM
587123 2017-05-14 22:00 PM 2017-05-14 23:00 PM
587123 2017-05-14 23:00 PM 2017-05-15 00:00 AM
587123 2017-05-15 00:00 AM 2017-05-15 01:00 AM
587123 2017-05-15 01:00 AM 2017-05-15 01:28 AM
My current code only splits the date/time range that is within the same day. For example, the time range for Employee 587123 stops the spliting at 22:00 - 23:00 and doesn't work for the time range in next day.
How do I update my code to capture data after midnight? (The last three rows in the sample result table.)
Here's my current code
SELECT YT.EmployeeCode,
CASE WHEN YT.StartDateTime > DT.StartDateTime THEN YT.StartDateTime ELSE DT.StartDateTime END AS StartDateTime,
CASE WHEN YT.EndDateTime < DT.EndDateTime THEN YT.EndDateTime ELSE DT.EndDateTime END AS StartDateTime
FROM (VALUES(843578,CONVERT(datetime2(0),'2017-05-14T08:30:00'),CONVERT(datetime2(0),'2017-05-14T15:36:00')),
(587123,CONVERT(datetime2(0),'2017-05-14T09:00:00'),CONVERT(datetime2(0),'2017-05-14T18:28:00')))YT(EmployeeCode,StartDateTime,EndDateTime)
CROSS APPLY (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23))T(I)
CROSS APPLY (VALUES(DATEADD(HOUR,T.I,CONVERT(time(0),'00:00:00')),DATEADD(HOUR,T.I+1,CONVERT(time(0),'00:00:00'))))V(StartTime,EndTime)
CROSS APPLY (VALUES(DATETIMEFROMPARTS(YEAR(YT.StartDateTime),MONTH(YT.StartDateTime),DAY(YT.StartDateTime),DATEPART(HOUR,V.StartTime),DATEPART(MINUTE,V.StartTime),0,0),
DATETIMEFROMPARTS(YEAR(YT.StartDateTime),MONTH(YT.StartDateTime),DAY(YT.StartDateTime),DATEPART(HOUR,V.EndTime),DATEPART(MINUTE,V.EndTime),0,0)))DT(StartDateTime,EndDateTime)
WHERE YT.StartDateTime <= DT.EndDateTime
AND YT.EndDateTime >= DT.StartDateTime;
The current code looks too complicated so if you know better way to do this, please let me know.
I'd appreciate any help on this.
Here is a recursive CTE solution:
with cte as (
select
employeecode,
startdatetime,
dateadd(hour, 1, datetimefromparts(year(startdatetime), month(startdatetime), day(startdatetime), datepart(hour, startdatetime), 0, 0, 0)) enddatetime
enddatetime maxdatetime
from mytable
union all
select employeecode, enddatetime, dateadd(hour, 1, enddatetime), maxdatetime
from cte
where enddatetime < maxdatetime
)
select employeecode, startdatetime,
case when enddatetime < maxdatetime then enddatetime else maxdatetime end as enddatetime
from cte
Basically, the anchor of the CTE performs computes the end of the first range, using datetimefrompart(). Then we iteratively generate the following ranges, until the maximum date time is reached. We can then display the results with the outer query, while adjusting the end date of the last range.
I would approach this using a recursive CTE:
with cte as (
select t.EmployeeCode, t.StartDateTime as startdt,
dateadd(hour, datepart(hour, t.startdatetime) + 1, convert(datetime, convert(date, t.StartDateTime))) as enddt,
t.endDateTime, 1 as lev
from t
union all
select cte.employeecode, enddt,
(case when dateadd(hour, 1, enddt) < enddatetime then dateadd(hour, 1, enddt) else enddatetime end),
enddatetime, lev + 1
from cte
where enddt < enddatetime
)
select *
from cte
order by employeecode, startdt;
Here is a db<>fiddle.
If you might have spans of more than 100 hours, then you need option (maxrecursion 0) for the query.

Need to Return all Available Time periods per Day per Location

I would like to find out how to 'roll up' the following table in Example 1 into Accumulated available time periods, as displayed in Example 2.
The following Code returns all the available Locations and the times that they are free by Day and by Half an hour timeslot.
I need to return the Available time in periods. EG if a location is available from 9am to 5pm that should be displayed.
Code to return Data:
SELECT
LTB.CalendarDate,
LTB.VenueCode,
LTB.VenueName,
LTB.LocationCode,
LTB.LocationDescription,
LTB.OpenTime,
LTB.CloseTime,
LTB.Weekday,
LTB.WeekdayName,
LTB.MaxUniqueParticipants,
LTB.TimeStartBlock,
LTB.TimeEndBlock
FROM
--LTB
--TimeBlock
(
SELECT LocationsOpenClose.CalendarDate,
LocationsOpenClose.StartTime,
LocationsOpenClose.EndTime,
LocationsOpenClose.VenueCode,
LocationsOpenClose.VenueName,
LocationsOpenClose.LocationCode,
LocationsOpenClose.LocationDescription,
LocationsOpenClose.Weekday,
LocationsOpenClose.WeekdayName,
LocationsOpenClose.MaxUniqueParticipants,
LocationsOpenClose.OpenTime,
LocationsOpenClose.CloseTime,
TimeDimension_2.[Time] AS TimeStartBlock,
DATEADD(SECOND, 1799, TimeDimension_2.[Time])
AS TimeEndBlock
--Locations Open Close
FROM (SELECT
dbo.LocationRoster.CalendarDate,
dbo.LocationRoster.StartTime,
dbo.LocationRoster.EndTime,
dbo.Venues.VenueCode,
dbo.Venues.VenueName,
dbo.Locations.LocationCode,
dbo.Locations.Description AS LocationDescription,
DateDimension.Weekday,
DateDimension.WeekdayName,
dbo.Locations.MaxUniqueParticipants,
TimeDimension.[Time] AS OpenTime,
TimeDimension_1.[Time] AS CloseTime
FROM dbo.LocationRoster
INNER JOIN dbo.Locations ON dbo.LocationRoster.LocationGUID = dbo.Locations.LocationGUID
INNER JOIN DateDimension ON dbo.LocationRoster.CalendarDate = DateDimension.[Date]
INNER JOIN TimeDimension ON dbo.LocationRoster.StartTime = TimeDimension.MinuteFromMidnight
INNER JOIN TimeDimension TimeDimension_1 ON dbo.LocationRoster.EndTime = TimeDimension_1.MinuteFromMidnight
INNER JOIN dbo.Venues ON dbo.Locations.VenueGUID = dbo.Venues.VenueGUID) AS LocationsOpenClose
RIGHT OUTER JOIN TimeDimension TimeDimension_2 ON TimeDimension_2.[Time] BETWEEN LocationsOpenClose.OpenTime AND DATEADD(SECOND, -1, LocationsOpenClose.CloseTime)
WHERE (LocationsOpenClose.CalendarDate BETWEEN '2018/08/15' AND '2018/08/16') ) AS LTB
--CETB
--CalendarEntriesStartFinish
LEFT OUTER JOIN
(
SELECT
CalendarEntriesStartFinish.CalendarEntryDate,
CalendarEntriesStartFinish.VenueCode,
CalendarEntriesStartFinish.VenueName,
CalendarEntriesStartFinish.LocationCode,
CalendarEntriesStartFinish.LocationDescription,
CalendarEntriesStartFinish.BookingStartTime,
CalendarEntriesStartFinish.BookingEndTime,
TimeDimension_2.[Time] AS TimeStartBlock,
DATEADD(SECOND, -1, TimeDimension_2.[Time]) AS TimeEndBlock,
CalendarEntriesStartFinish.ReferenceGUID
FROM
(
SELECT
CONVERT(DATE, dbo.CalendarEntries.StartDateTime) AS CalendarEntryDate,
dbo.Venues.VenueCode,
dbo.Venues.VenueName,
dbo.Locations.LocationCode,
dbo.Locations.Description AS LocationDescription,
CONVERT(TIME, dbo.CalendarEntries.StartDateTime) AS BookingStartTime,
DATEADD(SECOND,-1,CONVERT(TIME, dbo.CalendarEntries.FinishDateTime)) AS BookingEndTime,
dbo.CalendarEntries.ReferenceGUID
FROM dbo.CalendarEntries
INNER JOIN dbo.Locations ON dbo.CalendarEntries.LocationGUID = dbo.Locations.LocationGUID
INNER JOIN dbo.Venues ON dbo.Locations.VenueGUID = dbo.Venues.VenueGUID
WHERE (dbo.CalendarEntries.CalendarEntryType IN (0, 2)) AND (dbo.Locations.IsScheduled = 1)
) AS CalendarEntriesStartFinish
RIGHT OUTER JOIN TimeDimension TimeDimension_2 ON TimeDimension_2.[Time] BETWEEN CalendarEntriesStartFinish.BookingStartTime AND CalendarEntriesStartFinish.BookingEndTime
WHERE (CalendarEntriesStartFinish.CalendarEntryDate BETWEEN '2018/08/15' AND '2018/08/16')
) AS CETB ON LTB.CalendarDate = CONVERT(DATE,CETB.CalendarEntryDate) AND LTB.LocationCode = CETB.LocationCode AND LTB.TimeStartBlock = CETB.TimeStartBlock
WHERE (CETB.CalendarEntryDate IS NULL)
ORDER BY LTB.CalendarDate, LTB.LocationDescription, LTB.TimeStartBlock
Example 1: Current Result
CalendarDate VenueCode VenueName LocationCode LocationDescription OpenTime CloseTime Weekday WeekdayName MaxUniqueParticipants TimeStartBlock TimeEndBlock
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 08:30:00 08:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 09:00:00 09:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 11:00:00 11:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 11:30:00 11:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 12:00:00 12:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 12:30:00 12:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 16:00:00 16:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 16:30:00 16:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 17:00:00 17:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 17:30:00 17:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 18:00:00 18:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 18:30:00 18:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 19:00:00 19:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 19:30:00 19:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 20:00:00 20:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 20:30:00 20:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 21:00:00 21:29:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 21:30:00 21:59:59
The above shows all the available times by half an hour. It shows that A Location is not available from 13:00 to 16:00 on 15th August.
Example 2: Desired Result
CalendarDate VenueCode VenueName LocationCode LocationDescription OpenTime CloseTime Weekday WeekdayName MaxUniqueParticipants TimeStartBlock TimeEndBlock
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 08:30:00 12:59:59
15/08/2018 VC Venue Name Lcode A Location 05:30:00 22:00:00 4 Wednesday 20 16:00:00 21:59:59
So that they know A Location is free between 05:30 and 08:30 and then again between 16:00 and 22:00
The Time Dimension table is split in half hour intervals.
A colleague has suggested below, but I cannot get it to work.
WITH t AS (
SELECT LTB.CalendarDate d,ROW_NUMBER() OVER(ORDER BY LTB.CalendarDate) i
FROM #d
GROUP BY LTB.CalendarDate
)
SELECT MIN(d),MAX(d)
FROM t
GROUP BY DATEDIFF(day,i,d)
My SQL is not amazing so full explanations please, your help is appreciated.
here is an example, with my own test data
--build some sample data
select * into #tempt from
(
SELECT cast('20180515' as date) calendardate, 'VC' as VenueCode, CAST('08:30:00' as time) opentime, CAST('08:59:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VC' as VenueCode, CAST('09:00:00' as time) opentime, CAST('09:29:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VC' as VenueCode, CAST('09:30:00' as time) opentime, CAST('15:59:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VC' as VenueCode, CAST('16:30:00' as time) opentime, CAST('18:30:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VX' as VenueCode, CAST('08:30:00' as time) opentime, CAST('08:59:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VX' as VenueCode, CAST('09:00:00' as time) opentime, CAST('09:29:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VX' as VenueCode, CAST('09:45:00' as time) opentime, CAST('15:59:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VX' as VenueCode, CAST('16:45:00' as time) opentime, CAST('18:30:59' as time) closetime union
SELECT cast('20180515' as date) calendardate, 'VX' as VenueCode, CAST('18:31:00' as time) opentime, CAST('22:30:59' as time) closetime
) dq
--now do the work
--build a 'seconds in day' table using the first 3 CTE tables,
;with secs as (select 0 sc union all select sc + 1 from secs where sc < 59),
hrs as (select 0 hr union all select hr + 1 from hrs where hr < 23),
allt as (select dateadd(SECOND, s1.sc + m1.sc * 60 + h1.hr * 3600, CAST('00:00:00' as time)) t from secs s1, secs m1, hrs h1),
island as (select SQ.VenueCode,allt.t, case when exists(select 0 from #tempt tm WHERE SQ.VenueCode = tm.VenueCode and allt.t BETWEEN tm.opentime and tm.closetime) then 1 else 0 end x from allt cross join (SELECT distinct t3.VenueCode FROM #tempt t3) SQ), --calculation starts here
calc as (select VenueCode,t,x,ROW_NUMBER() over(partition by venuecode order by t) - ROW_NUMBER() over(partition by venuecode,x order by t) z from island) --asigns a number to all in an island
select VenueCode,x,MIN(t),MAX(t) from calc group by VenueCode, x,z having x = 1 order by venuecode, MIN(t) --summarises islands
--clear test data
drop table #tempt;

SQL - Order by time, then text on beginning

I have a query below :
SELECT DISTINCT TimeSched from tbl_schedule
It returns this result:
TimeSched
Rest Day
11:00 AM - 08:00 PM
No Schedule
09:00 AM - 06:00 PM
10:00 AM - 07:00 PM
When I use ORDER BY TimeSched, it returns this result:
TimeSched
09:00 AM - 06:00 PM
10:00 AM - 07:00 PM
11:00 AM - 08:00 PM
No Schedule
Rest Day
However, my desired result is I want 'Rest Day' and 'No Schedule' on the first and second row by default, then followed by the order of schedules in ascending order. As seen below :
TimeSched
Rest Day
No Schedule
09:00 AM - 06:00 PM
10:00 AM - 07:00 PM
11:00 AM - 08:00 PM
try this.
select * from timetable
order by
iif(timesched in ('No Schedule','Rest Day'),'01' + timesched,timesched)
Append a prefix for No Schedule and Restday with
01 when ordering.. so 01No will go 1, 01R will go next then your 09 to
24
How about simply doing:
SELECT DISTINCT TimeSched
FROM tbl_schedule
ORDER BY (CASE WHEN timesched LIKE '[a-zA-Z]%' THEN 1 ELSE 0 END),
timesched;
Try to make use of the below code :
DECLARE #TimeSched TABLE
(ID INT IDENTITY(1,1),TimeSched VARCHAR(20))
INSERT INTO #TimeSched
VALUES
('Rest Day'),
('11:00 AM - 08:00 PM'),
('No Schedule'),
('09:00 AM - 06:00 PM'),
('10:00 AM - 07:00 PM')
SELECT * FROM #TimeSched
ORDER BY
CASE
WHEN TimeSched ='Rest Day' THEN 1
WHEN TimeSched ='No Schedule' THEN 2
ELSE 3 END
Here is the answer to my question.
SELECT CASE TimeSched WHEN 'Restday' THEN 1 WHEN 'No Schedule' THEN 2 ELSE 3 END
AS TimeSked, TimeSched ORDER BY TimeSked, TimeSched

SQL Server 2012 - Using ROW_NUMBER() on DISTINCT [duplicate]

This question already has answers here:
sql query distinct with Row_Number
(8 answers)
Closed 5 years ago.
I have a query below.
SELECT DISTINCT
FORMAT(CAST(SchedTi AS DATETIME),'hh:mm tt') AS SchedTimeIn,
FORMAT(CAST(SchedTO AS DATETIME),'hh:mm tt') AS SchedTimeOut
FROM
tblemployee_schedule
ORDER BY
SchedTimeIn
It returns this resultset:
SchedTimeIn SchedTimeOut
01:00 AM 09:00 AM
01:00 AM 10:00 AM
01:00 AM 10:00 PM
01:15 AM 05:15 AM
01:15 AM 10:15 AM
01:30 AM 05:30 AM
01:30 PM 10:30 PM
01:45 AM 05:45 AM
My desired result is:
SchedTimeIn SchedTimeOut ROWNUM
01:00 AM 09:00 AM 1
01:00 AM 10:00 AM 2
01:00 AM 10:00 PM 3
01:15 AM 05:15 AM 4
01:15 AM 10:15 AM 5
01:30 AM 05:30 AM 6
01:30 PM 10:30 PM 7
01:45 AM 05:45 AM 8
I tried the following query:
SELECT DISTINCT
ROW_NUMBER() OVER(ORDER BY SchedTi),
FORMAT(CAST(SchedTi AS DATETIME),'hh:mm tt') AS SchedTimeIn,
FORMAT(CAST(SchedTO AS DATETIME),'hh:mm tt') AS SchedTimeOut
FROM
tblemployee_schedule
ORDER BY
SchedTimeIn
But it returns too many redundant rows and NULL values.
Thank you in advance.
Try the below one,
SELECT * ,ROW_NUMBER() OVER(ORDER BY SchedTimeIn) AS ROWNUM
FROM (
SELECT DISTINCT
FORMAT(CAST(SchedTi AS DATETIME),'hh:mm tt') AS SchedTimeIn,
FORMAT(CAST(SchedTO AS DATETIME),'hh:mm tt') AS SchedTimeOut
FROM tblemployee_schedule
) AS D
ORDER BY ROWNUM
In your query ROW_NUMBER() produce a new sequence number for each records , so the DISTINCT key will not wok for the same, that's why you are getting too many redundant records. So you can use the ROW_NUMBER() in an outer query to overcome this.
Main problem is you are asking only part of problem,
In firstplace using distinct,order by,row_number in same query seem wrong.
using only partition function is enough.
any way using your query,
select *
,ROW_NUMBER()over(order by SchedTimeIn)rn
FROM
(
SELECT DISTINCT
FORMAT(CAST(SchedTi AS DATETIME),'hh:mm tt') AS SchedTimeIn,
FORMAT(CAST(SchedTO AS DATETIME),'hh:mm tt') AS SchedTimeOut
FROM tblemployee_schedule
ORDER BY SchedTimeIn
)tbl