Ao aplicar a UNPIVOT
função a dados que não são normalizados, o SQL Server exige que o tipo de dados e o comprimento sejam os mesmos. Entendo por que o tipo de dados deve ser o mesmo, mas por que o UNPIVOT exige que o comprimento seja o mesmo?
Digamos que eu tenho os seguintes dados de exemplo que preciso desarticular:
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');
Se eu tentar UNPIVOT as colunas Firstname
e Lastname
semelhantes a:
select PersonId, ColumnName, Value
from People
unpivot
(
Value
FOR ColumnName in (FirstName, LastName)
) unpiv;
SQL Server gera o erro:
Msg 8167, nível 16, estado 1, linha 6
O tipo de coluna "Sobrenome" está em conflito com o tipo de outras colunas especificadas na lista UNPIVOT.
Para resolver o erro, devemos usar uma subconsulta para converter primeiro a Lastname
coluna para ter o mesmo comprimento que 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;
Veja SQL Fiddle com demonstração
Antes de o UNPIVOT ser introduzido no SQL Server 2005, eu usaria um SELECT
com UNION ALL
para descompactar as colunas firstname
/ lastname
e a consulta seria executada sem a necessidade de converter as colunas no mesmo comprimento:
select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;
Consulte SQL Fiddle com demonstração .
Também podemos descompactar os dados com êxito CROSS APPLY
sem ter o mesmo comprimento no tipo de dados:
select PersonId, columnname, value
from People
cross apply
(
select 'firstname', firstname union all
select 'lastname', lastname
) c (columnname, value);
Consulte SQL Fiddle com demonstração .
Eu li o MSDN, mas não encontrei nada explicando o motivo de forçar o comprimento do tipo de dados para o mesmo.
Qual é a lógica por trás da exigência do mesmo comprimento ao usar o UNPIVOT?