Podczas stosowania UNPIVOT
funkcji do danych, które nie są znormalizowane, SQL Server wymaga, aby typ danych i długość były takie same. Rozumiem, dlaczego typ danych musi być taki sam, ale dlaczego UNPIVOT wymaga, aby długość była taka sama?
Powiedzmy, że mam następujące przykładowe dane, które muszę rozdzielić:
CREATE TABLE People
(
PersonId int,
Firstname varchar(50),
Lastname varchar(25)
)
INSERT INTO People VALUES (1, 'Jim', 'Smith');
INSERT INTO People VALUES (2, 'Jane', 'Jones');
INSERT INTO People VALUES (3, 'Bob', 'Unicorn');
Jeśli spróbuję UNPIVOT Firstname
i Lastname
kolumny podobne do:
select PersonId, ColumnName, Value
from People
unpivot
(
Value
FOR ColumnName in (FirstName, LastName)
) unpiv;
SQL Server generuje błąd:
Msg 8167, poziom 16, stan 1, wiersz 6
Typ kolumny „Lastname” powoduje konflikt z typem innych kolumn określonych na liście UNPIVOT.
Aby rozwiązać błąd, musimy użyć podzapytania, aby najpierw rzutować Lastname
kolumnę, aby miała taką samą długość jak Firstname
:
select PersonId, ColumnName, Value
from
(
select personid,
firstname,
cast(lastname as varchar(50)) lastname
from People
) d
unpivot
(
Value FOR
ColumnName in (FirstName, LastName)
) unpiv;
Zobacz SQL Fiddle with Demo
Przed wprowadzeniem UNPIVOT w SQL Server 2005, używałbym znaku SELECT
z, UNION ALL
aby cofnąć przestawienie kolumn firstname
/, lastname
a zapytanie uruchamiałoby się bez potrzeby konwertowania kolumn na tę samą długość:
select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;
Zobacz SQL Fiddle with Demo .
Jesteśmy również w stanie z powodzeniem cofnąć przestawienie danych przy użyciu CROSS APPLY
tej samej długości w typie danych:
select PersonId, columnname, value
from People
cross apply
(
select 'firstname', firstname union all
select 'lastname', lastname
) c (columnname, value);
Zobacz SQL Fiddle with Demo .
Przeczytałem MSDN, ale nie znalazłem niczego, co tłumaczyłoby powód, dla którego zmuszono by długość typu danych była taka sama.
Jaka jest logika wymagająca tej samej długości podczas korzystania z UNPIVOT?