Existem várias maneiras de transformar dados de várias linhas em colunas.
Usando PIVOT
No SQL Server, você pode usar a PIVOT
função para transformar os dados de linhas em colunas:
select Firstname, Amount, PostalCode, LastName, AccountNumber
from
(
select value, columnname
from yourtable
) d
pivot
(
max(value)
for columnname in (Firstname, Amount, PostalCode, LastName, AccountNumber)
) piv;
Veja demonstração .
Pivô com número desconhecido de columnnames
Se você tiver um número desconhecido do columnnames
qual deseja transpor, poderá usar o SQL dinâmico:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(ColumnName)
from yourtable
group by ColumnName, id
order by id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = N'SELECT ' + @cols + N' from
(
select value, ColumnName
from yourtable
) x
pivot
(
max(value)
for ColumnName in (' + @cols + N')
) p '
exec sp_executesql @query;
Veja demonstração .
Usando uma função agregada
Se você não quiser usar a PIVOT
função, poderá usar uma função agregada com uma CASE
expressão:
select
max(case when columnname = 'FirstName' then value end) Firstname,
max(case when columnname = 'Amount' then value end) Amount,
max(case when columnname = 'PostalCode' then value end) PostalCode,
max(case when columnname = 'LastName' then value end) LastName,
max(case when columnname = 'AccountNumber' then value end) AccountNumber
from yourtable
Veja demonstração .
Usando várias junções
Isso também pode ser concluído usando várias junções, mas você precisará de alguma coluna para associar cada uma das linhas que você não possui em seus dados de amostra. Mas a sintaxe básica seria:
select fn.value as FirstName,
a.value as Amount,
pc.value as PostalCode,
ln.value as LastName,
an.value as AccountNumber
from yourtable fn
left join yourtable a
on fn.somecol = a.somecol
and a.columnname = 'Amount'
left join yourtable pc
on fn.somecol = pc.somecol
and pc.columnname = 'PostalCode'
left join yourtable ln
on fn.somecol = ln.somecol
and ln.columnname = 'LastName'
left join yourtable an
on fn.somecol = an.somecol
and an.columnname = 'AccountNumber'
where fn.columnname = 'Firstname'
cross join
e nãoleft join
porque cada subconsulta retorna uma linha.Este é um método, e não apenas um script, mas oferece muito mais flexibilidade.
Primeiro de tudo Existem 3 objetos:
ColumnActionList
] -> mantém dados como parâmetroproc_PivotPrepare
] -> prepara nossos dadosproc_PivotExecute
] -> executar o scriptCREATE TYPE [dbo]. [ColumnActionList] AS TABLE ([ID] [smallint] NOT NULL, [ColumnName] nvarchar NOT NULL, [Action] nchar NOT NULL); VAI
Ao executar a primeira consulta (passando o banco de dados de origem e o nome da tabela), você receberá uma consulta de execução pré-criada para o segundo SP, basta definir a coluna da sua fonte: + Estável + Valor (será usado para concentrar valores com base nisso) + Dim (coluna que você deseja usar para dinamizar)
Nomes e tipos de dados serão definidos automaticamente!
Não posso recomendá-lo para nenhum ambiente de produção, mas faz o trabalho para solicitações ad-hoc de BI.
fonte
Could not find stored procedure 'dbo.sp_PivotIt'.
Algum conselho?sp_Pivot_Execute
mude paraproc_PivotExecute
.