I am working on a routing system for a transportation type similar to a bus routing system like below.
I have a view that gives me the output. I need to pivot over schedules where the number of schedules can be of a variable quantity.
My query should result in the output given below in the image. I tried using Case Statements but I had problems with the number of rows returned.
Here are the scripts to generate the table and the data for reference:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ScheduleTest]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[ScheduleTest](
[StationName] [nvarchar](255) NULL,
[ScheduleNumber] [nvarchar](255) NULL,
[ArrivalTime] [nvarchar](20) NULL,
[DepartureTime] [nvarchar](20) NULL
) ON [PRIMARY]
END
GO
--Insert Scripts For Schedule A
Insert into ScheduleTest Values ('Chicago, IL, (Union Station)', 'ScheduleA', NULL, '02:45')
Insert into ScheduleTest Values ('Chicago, IL, (DownTown)', 'ScheduleA', '02:55', '03:00')
Insert into ScheduleTest Values ('Benton, MI, Harbor', 'ScheduleA', '08:00', NULL) --Benton in this case
--is final destination so departure time is null
-- Insert Scripts for Schedule B (Another Which runs in the morning)
Insert into ScheduleTest Values ('Chicago, IL, (Union Station)', 'ScheduleB', NULL, '06:00')
Insert into ScheduleTest Values ('Chicago, IL, (DownTown)', 'ScheduleB', '06:10', '06:15')
Insert into ScheduleTest Values ('Benton, IL, Harbor', 'ScheduleB', '11:00', NULL)
I don’t think I can use pivoting in Sql server 2005 since it needs some sort of aggregates to work on. I have nothing aggregate here.
I got it from a different source… This works and thanks to one who suggested this answer
IF OBJECT_ID( ‘tempdb..#ScheduleTest’) IS NOT NULL
DROP TABLE #ScheduleTest
GO
IF OBJECT_ID( ‘tempdb..#tmp’) IS NOT NULL
DROP TABLE #tmp
GO
CREATE TABLE #ScheduleTest(
[StationName] nvarchar NULL,
[ScheduleNumber] nvarchar NULL,
[ArrivalTime] nvarchar NULL,
[DepartureTime] nvarchar NULL
) ON [PRIMARY]
GO
–Insert Scripts For Schedule A
Insert into #ScheduleTest Values (‘Chicago, IL, (Union Station)’, ‘ScheduleA’, NULL, ’02:45′)
Insert into #ScheduleTest Values (‘Chicago, IL, (DownTown)’, ‘ScheduleA’, ’02:55′, ’03:00′)
Insert into #ScheduleTest Values (‘Benton, IL, Harbor’, ‘ScheduleA’, ’08:00′, NULL) –Benton in this case
–is final destination so departure time is null
— Insert Scripts for Schedule B (Another Which runs in the morning)
Insert into #ScheduleTest Values (‘Chicago, IL, (Union Station)’, ‘ScheduleB’, NULL, ’06:00′)
Insert into #ScheduleTest Values (‘Chicago, IL, (DownTown)’, ‘ScheduleB’, ’06:10′, ’06:15′)
Insert into #ScheduleTest Values (‘Benton, IL, Harbor’, ‘ScheduleB’, ’11:00′, NULL)
SELECT
StationName, ScheduleNumber, ArrivalTime AS TimeOfEvent, ‘Arrival’ AS [Arrival/Departure]
INTO #tmp
FROM
#ScheduleTest
WHERE
ArrivalTime IS NOT NULL
UNION ALL
SELECT
StationName, ScheduleNumber, DepartureTime AS TimeOfEvent, ‘Departure’ AS [Arrival/Departure]
FROM
#ScheduleTest
WHERE
DepartureTime IS NOT NULL
— Due to the aggregation requirement of pivot, Only one Schedule/Station combination is allowed.
— This is the query for the core data. Now, to dynamic this:
SELECT
StationName,
ScheduleA,
ScheduleB,
[Arrival/Departure]
FROM
#tmp AS t
PIVOT
( MAX(TimeOfEvent) FOR ScheduleNumber IN ( ScheduleA, ScheduleB)
) AS pvt
DECLARE @sql nVARCHAR(MAX),
@ScheduleNumber VARCHAR(50),
@PivotInList nVARCHAR(MAX)
SET @sql = ‘SELECT StationName, ‘
SET @PivotInList = ‘ IN (‘
DECLARE ScheduleCursor CURSOR FAST_FORWARD FOR
SELECT DISTINCT ScheduleNumber FROM #tmp
OPEN ScheduleCursor
FETCH NEXT FROM ScheduleCursor INTO @ScheduleNumber
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = @sql + @ScheduleNumber + ‘, ‘
SET @PivotInList = @PivotInList + ‘ ‘ + @ScheduleNumber + ‘,’
END
CLOSE ScheduleCursor
DEALLOCATE ScheduleCursor
SET @PivotInList = LEFT( @PivotInList, LEN( @PivotInList) – 1 /Remove the extra comma-space/) + ‘)’
PRINT @PivotInList
SET @sql = @sql + ‘[Arrival/Departure] FROM #tmp AS t PIVOT ( MAX( TimeOfEvent) FOR ScheduleNumber’
+ @PivotInList + ‘) AS pvt’
PRINT @sql
EXEC sp_executeSQL @sql