Pivot a fixed multiple column table in sql server

喜欢而已 提交于 2019-12-11 02:02:58

问题


I have a table which I need to pivot for reporting services:

DateCreated Rands   Units   Average Price   Success %   Unique Users
-------------------------------------------------------------------------
2013-08-26  0       0       0               0              0
2013-08-27  0       0       0               0              0
2013-08-28  10      2       5               100            1
2013-08-29  12      1       12              100            1
2013-08-30  71      9       8               100            1
2013-08-31  0       0       0               0              0
2013-09-01  0       0       0               0              0

In other words I need to have Rands, Units, Average Price etc at rows and the dates as columns.

I have read various examples but I just can't seem to get it right. Any help would be much appreciated!


回答1:


This one will do what you want, but you have to specify all the dates

select
   c.Name,
   max(case when t.DateCreated = '2013-08-26' then c.Value end) as [2013-08-26],
   max(case when t.DateCreated = '2013-08-27' then c.Value end) as [2013-08-27],
   max(case when t.DateCreated = '2013-08-28' then c.Value end) as [2013-08-28],
   max(case when t.DateCreated = '2013-08-29' then c.Value end) as [2013-08-29],
   max(case when t.DateCreated = '2013-08-30' then c.Value end) as [2013-08-30],
   max(case when t.DateCreated = '2013-08-31' then c.Value end) as [2013-08-31],
   max(case when t.DateCreated = '2013-09-01' then c.Value end) as [2013-09-01]
from test as t
   outer apply (
       select 'Rands', Rands union all
       select 'Units', Units union all
       select 'Average Price', [Average Price] union all
       select 'Success %', [Success %] union all
       select 'Unique Users', [Unique Users]
   ) as C(Name, Value)
group by c.Name

You can create a dynamic SQL for this, something like this:

declare @stmt nvarchar(max)

select @stmt = isnull(@stmt + ',', '') + 
    'max(case when t.DateCreated = ''' + convert(nvarchar(8), t.DateCreated, 112) + ''' then c.Value end) as [' + convert(nvarchar(8), t.DateCreated, 112) + ']'
from test as t

select @stmt = '
   select
       c.Name, ' + @stmt + ' from test as t
   outer apply (
       select ''Rands'', Rands union all
       select ''Units'', Units union all
       select ''Average Price'', [Average Price] union all
       select ''Success %'', [Success %] union all
       select ''Unique Users'', [Unique Users]
   ) as C(Name, Value)
   group by c.Name'

exec sp_executesql @stmt = @stmt



回答2:


I solved this in the end using dynamic sql, very similar to the marked answer. I wasn't able to find a way of doing this without dynamic sql. The dates had to be in order and the last 7 days, they also had to use the day of the week names (which I didn't specify in the question).

The biggest change I needed to make was changing the table variable into a temporary table. This is because dynamic sql statements execute in a different context and don't know about any variables you have created.

In the end I was completely off track trying to use PIVOT and APPLY should be used in situations where there are more than one "type" of value.

I have included my solution below since it could help someone who has a similar problem:

CREATE TABLE #SummaryTable
(
    [DateCreated] DATE UNIQUE,
    [Rands] DECIMAL,
    [Units] INT,
    [Average Price] DECIMAL,
    [Success %] INT,
    [Unique Users] INT
);

--Code to fill table

declare @stmt nvarchar(max)

select @stmt = isnull(@stmt + ',', '') + 
    'max(case when t.DateCreated = ''' + convert(nvarchar(16), t.DateCreated, 126)
 + ''' then c.Value end) as [' + left(datename(dw, t.DateCreated),3) + ']'
from #SummaryTable as t

select @stmt = '
   select
       c.Name, ' + @stmt + ' from #SummaryTable as t
   outer apply (
       select ''Rands'', Rands union all
       select ''Units'', Units union all
       select ''Average Price'', [Average Price] union all
       select ''Success'', [Success %] union all
       select ''Unique Users'', [Unique Users]
   ) as C(Name, Value)
   group by c.Name'

exec(@stmt)


来源:https://stackoverflow.com/questions/18575984/pivot-a-fixed-multiple-column-table-in-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!