Related
This question already has answers here:
How to replace (null) values with 0 output in PIVOT
(7 answers)
Closed 3 years ago.
I've been trying to remove NULL values from a pivot table. I've tried several suggested solutions to without luck.
Declare #toName as nvarchar(max)
SELECT *
FROM (SELECT
isnull(protocol,0) as Protocol,
isnull(callCategory,0) as DCRCategory,
isnull(DATEPART(Year, eCreationTime),0) AS Year,
isnull(DATENAME(MONTH, eCreationTime),0) [Month],
isnull(COUNT(1),0) callCategory
FROM DCR_DATA
where ProjectManager = ''' + #toName + '''
GROUP BY protocol, callCategory, YEAR(eCreationTime), DATENAME(MONTH, eCreationTime))
AS MontlyDCRData
PIVOT(SUM(callCategory)
FOR Month IN ([January],[February],[March],[April],[May],
[June],[July],[August],[September],[October],[November],
[December])) AS MNamePivot
Here is an example of what I am returning:
Protocol DCRCategory Year January February March April May June July August September October November December
123 Cat 1 2017 NULL NULL NULL NULL NULL NULL NULL NULL 4 NULL NULL NULL
DECLARE #cols AS NVARCHAR(MAX),#cols1 AS NVARCHAR(MAX),#query AS NVARCHAR(MAX)
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(+'ISNULL('+CAST(ColName AS VARCHAR) +' ,0)' ) + ' ' + QUOTENAME(ColName)
FROM TblName
GROUP BY ColName
ORDER BY ColName
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT #cols1 = STUFF((SELECT ',' + QUOTENAME(ColName)
from TblName
group by ColName
order by ColName
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT ColName1,' + #cols + ' from
(
SELECT ColName1, ColName2, ColName3
FROM TblName
) x
PIVOT
(
SUM(ColName3)
FOR ColName2 IN (' + #cols1 + ')
) p '
EXECUTE(#query);
Not the most elegant solution, but here goes -> Select into a temp table
Declare #toName as nvarchar(max)
SELECT *
INTO #tmpTable
FROM (SELECT isnull(protocol,0) as Protocol
, isnull(callCategory,0) as DCRCategory
, isnull(DATEPART(Year, eCreationTime),0) AS Year
, isnull(DATENAME(MONTH, eCreationTime),0) [Month]
, isnull(COUNT(1),0) callCategory
FROM DCR_DATA
where ProjectManager = ''' + #toName + '''
GROUP BY protocol
, callCategory
, YEAR(eCreationTime)
, DATENAME(MONTH, eCreationTime))
AS MontlyDCRData
PIVOT(SUM( callCategory)
FOR Month IN ([January],[February],[March],[April],[May],
[June],[July],[August],[September],[October],[November],
[December])) AS MNamePivot
and then isnull from there.
SELECT tmp.Protocol, tmp.DCRCategory, tmp.[Year]
, isnull(tmp.January,0)
, ...
, isnull(tmp.December,0)
FROM #tmpTable as tmp
I have a table which has records in the following format:
OrderID | CategoryID | Percentage
-----------------------------------------
Order1 1 50
Order1 2 100
Order1 3 70
Order2 1 85
Order2 2 75
Order2 3 100
Order3 1 50
Order3 2 60
Order3 3 80
Each order has multiple categories and each category has a percentage corresponding to that order.
I want to display it in the following format:
OrderID | Category1_% | Category2_% | Category3_%
-------------------------------------------------------
Order1 50 100 70
Order2 85 75 100
Order3 50 60 80
How do I write a query in SQL Server 2008 to retrieve percentages for each category of each (distinct) order? Please help.
Edit:
Orders table
ID | StartDate
--------------------
Order1 1/1/2016
Order2 10/1/2015
Order3 10/5/2016
The query which I executed is:
Declare #SQL varchar(max)
Declare #startDate datetime
set #startDate='1/1/2015'
Declare #endDate datetime
set #endDate= '10/1/2016'
Select #SQL = Stuff((Select Distinct ',' + QuoteName('Category'+cast(CategoryID as varchar(25))+'_%') From OrdersData Order By 1 For XML Path('')),1,1,'')
Select #SQL = 'Select [OrderID],' + #SQL +'
From (Select OrderID,Percentage,Item=''Category''+cast(CategoryID as varchar(25))+''_%'' from OrdersData join Orders on Orders.ID =OrdersData.OrderID
WHERE Orders.StartDate >= '+ ***convert(nvarchar(25), #startDate, 121)*** + ' and GCWR.StartDate <= '+ ***convert(nvarchar(25), #endDate, 121)*** +') A
Pivot (max(Percentage) For Item in (' + #SQL + ') ) p'
Exec(#SQL);
When I execute, I get an error 'Incorrect syntax near '00'.' How do I call the datetime values in the above query to display the results? Please let me know.
Just in case you need to go dynamic
Declare #SQL varchar(max)
Select #SQL = Stuff((Select Distinct ',' + QuoteName('Category'+cast(CategoryID as varchar(25))+'_%') From YourTable Order By 1 For XML Path('')),1,1,'')
Select #SQL = 'Select [OrderID],' + #SQL +'
From (Select OrderID,Percentage,Item=''Category''+cast(CategoryID as varchar(25))+''_%'' from YourTable) A
Pivot (max(Percentage) For Item in (' + #SQL + ') ) p'
Exec(#SQL);
Returns
Edit - Updated with StartDate
Declare #Date1 datetime = '2015-01-01'
Declare #Date2 datetime = '2016-10-01'
Declare #SQL varchar(max)
Select #SQL = Stuff((Select Distinct ',' + QuoteName('Category'+cast(CategoryID as varchar(25))+'_%') From YourTable Where cast(StartDate as date) between #Date1 and #Date2 Order By 1 For XML Path('')),1,1,'')
Select #SQL = 'Select [OrderID],' + #SQL +'
From (Select OrderID,Percentage,Item=''Category''+cast(CategoryID as varchar(25))+''_%'' from YourTable Where cast(StartDate as date) between '''+convert(varchar(10),#Date1,120)+''' and '''+convert(varchar(10),#Date2,120)+''') A
Pivot (max(Percentage) For Item in (' + #SQL + ') ) p'
Exec(#SQL);
Returns
Give this a try:
Select OrderID, [1] as [Category1_%], [2] as [Category2_%],[3] as [Category3_%]
From [TableName]
PIVOT (MAX([Percentage]) FOR [CategoryID] IN ([1],[2],[3])) myPivot
This assumes that you know all the possible values in the categoryID field and that each CategoryID an OrderID combination has a single percentage value.
I have an Excel-sheet as below, I already dump the data into database (as the sample data below) from this excel in normalized form.
Now I want to get the similar view of excel from database's data. I tried this, but given in wrong format. Good if somebody given the same result view as excel with column name and inner join.
I do not want to hardcore as the year expand.
declare #tblyear table(id int, year int)
insert into #tblyear values (1,2012), (2,2013),(3,2014) ,(4,2015),(5,2016)
declare #ChargeableYearDetails table ( id int, year int, CumulativeHrs numeric(18,2), CumulativeChargeableHrs numeric(18,2))
--take only 2 row year wise for the sample
insert into #ChargeableYearDetails values
(1, 1, 1657.75, 1243.50),
(2, 1, 3925.50, 3044.75),
(3, 2, 870.25, 568.25),
(4, 2, 2517.75, 1808.00),
(5, 3, 189.50, 99.00),
(6, 3, 1982.75, 1295.25),
(7, 4, 539.00, 351.00),
(8, 4, 2542.75, 1924.75),
(9, 5, 874.50, 596.50),
(9, 5, 2721.50, 2175.50)
select * from #tblyear
select * from #ChargeableYearDetails
/*I tried this , but given wrong result*/
select * from #ChargeableYearDetails
pivot
(
max(CumulativeHrs)
FOR year in ([1],[2],[3],[4],[5])
) as p
My answer is a little bit complicated, but I should post it. I use dynamic sql and pivoting.
DECLARE #columnsH nvarchar(500),
#columnsCH nvarchar(500),
#columns nvarchar(1000),
#sql nvarchar(4000)
CREATE TABLE #tblyear (id int, [year] int)
INSERT INTO #tblyear VALUES (1,2012), (2,2013),(3,2014) ,(4,2015),(5,2016)
CREATE TABLE #ChargeableYearDetails (id int, [year] int, CumulativeHrs numeric(18,2), CumulativeChargeableHrs numeric(18,2))
INSERT INTO #ChargeableYearDetails VALUES
(1, 1, 1657.75, 1243.50),(2, 1, 3925.50, 3044.75),(3, 2, 870.25, 568.25),
(4, 2, 2517.75, 1808.00),(5, 3, 189.50, 99.00),(6, 3, 1982.75, 1295.25),
(7, 4, 539.00, 351.00),(8, 4, 2542.75, 1924.75),(9, 5, 874.50, 596.50),
(9, 5, 2721.50, 2175.50)
SELECT #columnsH = STUFF((SELECT DISTINCT ',' + QUOTENAME('CumulativeHrsYY'+ CAST([Year] AS NVARCHAR(4))) FROM #tblyear FOR XML PATH('')),1,1,'')
SELECT #columnsCH = STUFF((SELECT DISTINCT ',' + QUOTENAME('CumulativeChargeableHrs'+ CAST([Year] AS NVARCHAR(4))) FROM #tblyear FOR XML PATH('')),1,1,'')
SELECT #columns = STUFF((SELECT DISTINCT ',' + QUOTENAME('CumulativeHrsYY'+ CAST([Year] AS NVARCHAR(4))) +',' + QUOTENAME('CumulativeChargeableHrs'+ CAST([Year] AS NVARCHAR(4))) FROM #tblyear FOR XML PATH('')),1,1,'')
SELECT #sql = '
SELECT '+ #columns+'
FROM (
SELECT *
FROM (
SELECT ''CumulativeHrsYY''+ CAST(t.[Year] AS NVARCHAR(4)) as [Year],
c.CumulativeHrs,
ROW_NUMBER() OVER (PARTITION BY c.[year] ORDER BY c.[year]) as rn
FROM #ChargeableYearDetails c
LEFT JOIN #tblyear t
ON t.ID = c.[year]
) as t
pivot
(
max(CumulativeHrs)
FOR [year] in ('+#columnsH+')
) as p
) as part1
LEFT JOIN (
SELECT *
FROM (
SELECT ''CumulativeChargeableHrs''+ CAST(t.[Year] AS NVARCHAR(4)) as [Year],
c.CumulativeChargeableHrs,
ROW_NUMBER() OVER (PARTITION BY c.[year] ORDER BY c.[year]) as rn
FROM #ChargeableYearDetails c
LEFT JOIN #tblyear t
ON t.ID = c.[year]
) as t
pivot
(
max(CumulativeChargeableHrs)
FOR [year] in ('+#columnsCH+')
) as p
) as part2
ON part1.rn = part2.rn'
EXEC(#sql)
DROP TABLE #ChargeableYearDetails
DROP TABLE #tblyear
Output:
CumulativeHrsYY2012 CumulativeChargeableHrs2012 CumulativeHrsYY2013 CumulativeChargeableHrs2013 CumulativeHrsYY2014 CumulativeChargeableHrs2014 CumulativeHrsYY2015 CumulativeChargeableHrs2015 CumulativeHrsYY2016 CumulativeChargeableHrs2016
1657.75 1243.50 870.25 568.25 189.50 99.00 539.00 351.00 874.50 596.50
3925.50 3044.75 2517.75 1808.00 1982.75 1295.25 2542.75 1924.75 2721.50 2175.50
Using dynamic sql, something like this will work. Have changed your table var to temp tables. You will have to change it to accommodate for multiple rows. Just add a group by to the pivot. Pls refer this msdn blog post on how to pivot on multiple fields
DECLARE #cols AS NVARCHAR(MAX), #cols2 AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME('Cumulative Hours ' + cast(year as varchar(4)))
from #tblyear
group by year, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #cols2 = STUFF((SELECT ',' + QUOTENAME('Cumulative Chargable Hours ' + cast(year as varchar(4)))
from #tblyear
group by year, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
DECLARE #colsMax AS NVARCHAR(MAX), #cols2Max AS NVARCHAR(MAX)
select #colsMax = STUFF((SELECT ', MAX(' + QUOTENAME('Cumulative Hours ' + cast(year as varchar(4))) + ') ' + QUOTENAME('Cumulative Hours ' + cast(year as varchar(4)))
from #tblyear
group by year, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #cols2Max = STUFF((SELECT ', MAX(' + QUOTENAME('Cumulative Chargable Hours ' + cast(year as varchar(4))) + ') ' + QUOTENAME('Cumulative Chargable Hours ' + cast(year as varchar(4)))
from #tblyear
group by year, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #colsMax + ',' + #cols2Max + N' from
(
select CumulativeHrs, CumulativeChargeableHrs
, ''Cumulative Hours '' + cast(b.year as varchar(4)) as [CumHours]
, ''Cumulative Chargable Hours '' + cast(b.year as varchar(4)) as [CumChargableHours]
from #ChargeableYearDetails a join #tblyear b on a.year = b.id
) query
pivot
(
max(CumulativeHrs)
for CumHours in (' + #cols + N')
) p
pivot
(
max(CumulativeChargeableHrs)
for CumChargableHours in (' + #cols2 + N')
) p2
'
print #query
exec sp_executesql #query;
You can do this using dynamic sql.. this will create some MAX(CASE WHEN) statements for each year/hrs combo.. then execute the sql by using EXEC sp_executesql #sql or just EXEC(#sql)
DECLARE #Sql NVARCHAR(MAX),
#Cols NVARCHAR(MAX)
SELECT #Cols = COALESCE(#Cols + ', ', '') +
'MAX(CASE WHEN Year = ' + CAST(id AS VARCHAR) + ' THEN CumulativeHrs END) AS [Cumulative Hrs YTD - ' + CAST([year] AS VARCHAR) + '], ' +
'MAX(CASE WHEN Year = ' + CAST(id AS VARCHAR) + ' THEN CumulativeChargeableHrs END) AS [Cumulative Chargeable Hrs ' + CAST([year] AS VARCHAR) + '] '
FROM tblyear
ORDER BY [year] DESC
SET #Sql = 'SELECT ' + #Cols
+ ' FROM (SELECT *, Row_number() Over (Partition by [year] order by id) Rn FROM ChargeableYearDetails) t '
+ ' GROUP BY Rn'
EXEC sp_executesql #Sql
you won't be able to use table variables in this type of query without defining them as types first, but i'm guessing you're using actual tables.
Row_number was also added to break each record per year into separate rows
It is possible to use the PIVOT clause, but this has two disadvantages. Firstly, it can only pivot a single column. Secondly it can't handle dynamic columns; you have to pre-specify them.
In this example, I'm using two CTEs to pivot each column, then joining the result sets.
You might do better to implement this in a mid-tier layer programmed in C#.
WITH cteHrs AS
(
SELECT id, [1], [2], [3], [4], [5]
FROM
(SELECT id, [year], CumulativeHrs
FROM #ChargeableYearDetails) AS H
PIVOT
(
SUM(CumulativeHrs)
FOR [year] IN ([1], [2], [3], [4], [5])
) as pvtH
),
cteChgHrs AS
(
SELECT id, [1], [2], [3], [4], [5]
FROM
(SELECT id, [year], CumulativeChargeableHrs
FROM #ChargeableYearDetails) AS C
PIVOT
(
SUM(CumulativeChargeableHrs)
FOR [year] IN ([1], [2], [3], [4], [5])
) as pvtC
)
SELECT COALESCE(C.id, H.id) AS 'id',
C.[1] AS 'Cum Hrs 2012', H.[1] AS 'Cum Chg Hrs 2012',
C.[2] AS 'Cum Hrs 2013', H.[2] AS 'Cum Chg Hrs 2013',
C.[3] AS 'Cum Hrs 2014', H.[3] AS 'Cum Chg Hrs 2014',
C.[4] AS 'Cum Hrs 2015', H.[4] AS 'Cum Chg Hrs 2015',
C.[5] AS 'Cum Hrs 2016', H.[5] AS 'Cum Chg Hrs 2016'
FROM cteHrs AS H
FULL OUTER JOIN cteChgHrs AS C
ON C.id = H.id;
The result set is this.
I have a stored procedure like this:
ALTER PROCEDURE [dbo].[ParkingDeatailsReportnew]
#startdate NVARCHAR(100),
#enddate NVARCHAR(100)AS BEGINDECLARE #cols AS NVARCHAR(MAX) , #query AS NVARCHAR(MAX)
SELECT #cols = STUFF(( SELECT DISTINCT ',' + QUOTENAME(Vtype)
FROM dbo.VType_tbl FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query =
'SELECT LocName,Date, ' + #cols + '
from (
select l.LocName,v.Vtype, convert(date, dtime) as Date
from Transaction_tbl t
join VType_tbl v on t.vtid = v.vtid
where dtime between ''' + #startdate + ''' and ''' + #enddate + '''
and locid IN (SELECT l.Locid FROM dbo.Location_tbl l)
) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p ' EXEC sys.sp_executesql #query
END
I am getting out put like this:
Date Emaar Staff Lost Ticket Normal VIP VVIP
---------- ----------- ----------- ----------- ----------- -----------
2013-05-08 1 0 12 6 3
2013-05-09 0 0 1 0 0
I have one more table name location table.i want to show particular location name(locname) also in my output
expected output
Location Date Emaar Staff Lost Ticket Normal VIP VVIP
------- -- - ---------- ----------- ----------- ----------- ----------- -----------
Fasion 2013-05-08 1 0 12 6 3
blooimg 2013-05-09 0 0 1 0 0
If you want to see the location outputted, you need to include it in your select
'SELECT Location, Date, ' + #cols + '
from (
select Location, v.Vtype, convert(date, dtime) as Date
....
Im using MS SQL Server 2008
Table name is tblDateTimeLog:
ID INT(AI)
RecordID INT
DateLog DATE
TimeLog TIME
DetachmentCode INT
EntryDate DATETIME
IsDeleted BIT
UserID VARCHAR(50)
I have a table containing this:
RecordID | DateLog | TimeLog
11 | 2013-06-01 | 07:59:00
11 | 2013-06-01 | 19:01:00
11 | 2013-06-02 | 07:57:00
11 | 2013-06-02 | 19:03:00
11 | 2013-06-03 | 07:49:00
11 | 2013-06-03 | 19:11:00
14 | 2013-06-04 | 08:01:00
14 | 2013-06-04 | 19:03:00
14 | 2013-06-05 | 07:52:00
14 | 2013-06-05 | 19:02:00
One Record ID can have multiple TimeLog on the same DateLog
Now I want it to show like this:
The Dates as columns and the Total No. of Hours between MIN(TimeLog) and MAX(TimeLog)
RecordID | 2013-06-01 | 2013-06-02 | 2013-06-03 | 2013-06-04 | 2013-06-05
11 | 11:02:00 | 11:06:00 | 11:22:00 | NULL | NULL
14 | NULL | NULL | NULL | 11:02:00 | 11:10:00
As per Mikael's Answer, this works but as I understand his query, this returns MIN(TimeLog):
DECLARE #SQL NVARCHAR(MAX)
DECLARE #ColumnList NVARCHAR(MAX)
SELECT #ColumnList =
STUFF
(
(
SELECT DISTINCT ','+QUOTENAME(DateLog)
FROM TESTPIS.dbo.tblDateTimeLog
WHERE IsDeleted=0 AND DateLog >= '2013-06-15' AND DateLog <= '2013-06-30'
ORDER BY 1
FOR XML PATH('')
), 1, 1, ''
)
SET #SQL = 'SELECT P.RecordID, '+#ColumnList+'
FROM
(
SELECT RecordID, TimeLog, DateLog FROM TESTPIS.dbo.tblDateTimeLog WHERE isDeleted=0
) AS T
PIVOT
(
MIN(TimeLog) FOR DateLog IN ('+#ColumnList+')
) as P'
EXEC (#SQL)
What I want to return is like DATEDIFF(MINUTES,MIN(TimeLog),MAX(TimeLog)
I tried replacing the MIN(TimeLog) in the query with this
SUM(DATEDIFF(MINUTES,MIN(TimeLog),MAX(TimeLog))
However, I got this error
Incorrect syntax near '('.
select P.RecordID,
P.[2013-06-01],
P.[2013-06-02],
P.[2013-06-03],
P.[2013-06-04],
P.[2013-06-05]
from (
select RecordID,
TimeLog,
DateLog
from YourTable
) as T
pivot(min(TimeLog) for DateLog in ([2013-06-01],
[2013-06-02],
[2013-06-03],
[2013-06-04],
[2013-06-05])) as P
To build the query dynamically you have to first figure out what the column list should contain.
select distinct DateLog
from YourTable
order by 1
The result from that query has to be turned into a comma separated list and since numbers like that is invalid column names you can use quotename() to enclose the value in [].
To build the comma separated list of column you can use for xml path('').
select stuff((select distinct ','+quotename(DateLog)
from YourTable
order by 1
for xml path('')), 1, 1, '')
stuff() is there to remove the first comma.
Then you just need to put it all together and execute the query you have built.
declare #SQL nvarchar(max)
declare #ColumnList nvarchar(max)
select #ColumnList = stuff((select distinct ','+quotename(DateLog)
from YourTable
order by 1
for xml path('')), 1, 1, '')
set #SQL = '
select P.RecordID, '+#ColumnList+'
from (
select RecordID,
TimeLog,
DateLog
from YourTable
) as T
pivot(min(TimeLog) for DateLog in ('+#ColumnList+')) as P'
exec (#SQL)
SQL Fiddle
Update
To get the diff between max and min timelog value for each day you can do a group by on RecordID and DateLog in the derived table and calculate the diff in seconds between min and max and use that value to calculate a new time value using dateadd.
select P.RecordID,
P.[2013-06-01],
P.[2013-06-02],
P.[2013-06-03],
P.[2013-06-04],
P.[2013-06-05]
from (
select RecordID,
dateadd(second, datediff(second, min(TimeLog), max(TimeLog)), convert(time(0), '00:00')) as TimeDiff,
DateLog
from YourTable
group by RecordID,
DateLog
) as T
pivot(min(TimeDiff) for DateLog in ([2013-06-01],
[2013-06-02],
[2013-06-03],
[2013-06-04],
[2013-06-05])) as P
Dynamic version:
declare #SQL nvarchar(max)
declare #ColumnList nvarchar(max)
select #ColumnList = stuff((select distinct ','+quotename(DateLog)
from YourTable
order by 1
for xml path('')), 1, 1, '')
set #SQL = '
select P.RecordID, '+#ColumnList+'
from (
select RecordID,
dateadd(second, datediff(second, min(TimeLog), max(TimeLog)), convert(time(0), ''00:00'')) as TimeDiff,
DateLog
from YourTable
group by RecordID,
DateLog
) as T
pivot(min(TimeDiff) for DateLog in ('+#ColumnList+')) as P'
exec (#SQL)
SQL Fiddle
Try this one -
Query:
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
RecordID INT
, DateLog DATETIME
, TimeLog TIME
)
INSERT INTO #temp (RecordID, DateLog, TimeLog)
VALUES
(11, '2013-06-01', '08:00:00'), (11, '2013-06-02', '09:00:00'),
(11, '2013-06-03', '10:00:00'), (11, '2013-06-04', '11:00:00'),
(11, '2013-06-05', '12:00:00'), (14, '2013-06-01', '13:00:00'),
(14, '2013-06-02', '14:00:00'), (14, '2013-06-03', '15:00:00'),
(14, '2013-06-04', '16:00:00')
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = 'SELECT *
FROM (
SELECT DateLog, RecordID, tt = CAST(TimeLog AS VARCHAR(8))
FROM #temp
) src
PIVOT (
MAX(tt)
FOR DateLog IN (' + STUFF((
SELECT ', [' + CONVERT(VARCHAR(10), DateLog, 120) + ']'
FROM #temp
GROUP BY DateLog
ORDER BY DateLog
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') + ')
) p'
PRINT #SQL
EXEC sys.sp_executesql #SQL
Output:
SELECT *
FROM (
SELECT DateLog, RecordID, tt = CAST(TimeLog AS VARCHAR(8))
FROM #temp
) src
PIVOT (
MAX(tt)
FOR DateLog IN ([2013-06-01], [2013-06-02], [2013-06-03], [2013-06-04], [2013-06-05])
) p
Results:
RecordID 2013-06-01 2013-06-02 2013-06-03 2013-06-04 2013-06-05
----------- ---------- ---------- ---------- ---------- ----------
11 08:00:00 09:00:00 10:00:00 11:00:00 12:00:00
14 13:00:00 14:00:00 15:00:00 16:00:00 NULL
Update with results: