Istnieje kilka sposobów przekształcania danych z wielu wierszy w kolumny.
Za pomocą PIVOT
W SQL Server można użyć PIVOT
funkcji do transformacji danych z wierszy do kolumn:
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;
Zobacz demo .
Pivot z nieznaną liczbą columnnames
Jeśli masz nieznaną liczbę columnnames
, którą chcesz przetransponować, możesz użyć dynamicznego SQL:
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;
Zobacz demo .
Korzystanie z funkcji agregującej
Jeśli nie chcesz korzystać z PIVOT
funkcji, możesz użyć funkcji agregującej z CASE
wyrażeniem:
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
Zobacz demo .
Używanie wielu sprzężeń
Można to również wykonać za pomocą wielu sprzężeń, ale będziesz potrzebować kolumny, aby powiązać każdy wiersz, którego nie masz w przykładowych danych. Ale podstawową składnią byłoby:
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
zamiast tego,left join
ponieważ każde podzapytanie zwraca jeden wiersz.Jest to raczej metoda niż pojedynczy skrypt, ale zapewnia znacznie większą elastyczność.
Przede wszystkim są 3 obiekty:
ColumnActionList
] -> przechowuje dane jako parametrproc_PivotPrepare
] -> przygotowuje nasze daneproc_PivotExecute
] -> uruchom skryptCREATE TYPE [dbo]. [ColumnActionList] AS TABLE ([ID] [smallint] NOT NULL, [ColumnName] nvarchar NOT NULL, [Action] nchar NOT NULL); UDAĆ SIĘ
Po wykonaniu pierwszego zapytania (przekazując źródłową bazę danych i nazwę tabeli) otrzymasz wstępnie utworzone zapytanie wykonawcze dla drugiego SP, wszystko co musisz zrobić, to zdefiniować kolumnę ze źródła: + Stabilna + Wartość (zostanie użyta aby skoncentrować oparte na nim wartości) + Dim (kolumna, której chcesz użyć do przestawienia)
Nazwy i typy danych zostaną zdefiniowane automatycznie!
Nie mogę go polecić w żadnym środowisku produkcyjnym, ale spełnia swoje zadanie w przypadku żądań BI adhoc.
źródło
Could not find stored procedure 'dbo.sp_PivotIt'.
jakaś rada?sp_Pivot_Execute
zmień naproc_PivotExecute
.