При применении UNPIVOT
функции к ненормализованным данным SQL Server требует, чтобы тип данных и длина были одинаковыми. Я понимаю, почему тип данных должен быть одинаковым, но почему UNPIVOT требует одинаковую длину?
Допустим, у меня есть следующие примеры данных, которые мне нужно отключить:
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');
Если я попытаюсь UNPIVOT Firstname
и Lastname
столбцы, похожие на:
select PersonId, ColumnName, Value
from People
unpivot
(
Value
FOR ColumnName in (FirstName, LastName)
) unpiv;
SQL Server генерирует ошибку:
Сообщение 8167, уровень 16, состояние 1, строка 6
Тип столбца «Фамилия» конфликтует с типом других столбцов, указанных в списке UNPIVOT.
Чтобы устранить ошибку, мы должны использовать подзапрос, чтобы сначала привести Lastname
столбец такой же длины, как 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;
Смотрите SQL Fiddle с демо
До введения UNPIVOT в SQL Server 2005 я использовал команду SELECT
with, UNION ALL
чтобы отключить столбцы firstname
/, lastname
и запрос выполнялся без необходимости преобразования столбцов одинаковой длины:
select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;
Смотрите SQL Fiddle с демонстрацией .
Мы также можем успешно отключить данные, используя CROSS APPLY
одинаковую длину для типа данных:
select PersonId, columnname, value
from People
cross apply
(
select 'firstname', firstname union all
select 'lastname', lastname
) c (columnname, value);
Смотрите SQL Fiddle с демонстрацией .
Я прочитал MSDN, но не нашел ничего, объясняющего причины, по которым длина типа данных была бы одинаковой.
Какая логика лежит в основе требования одинаковой длины при использовании UNPIVOT?