Застосовуючи 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 генерує помилку:
Msg 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 with Demo
До UNPIVOT вводиться в SQL Server 2005, я б використовувати SELECTз , UNION ALLщоб UNPIVOT в firstname/ lastnameстовпців і запит буде виконуватися без необхідності перетворення стовпців в одній і тій же довжини:
select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;
Див. SQL Fiddle with Demo .
Ми також можемо успішно розкручувати дані, використовуючи CROSS APPLYбез однакової довжини на тип даних:
select PersonId, columnname, value
from People
cross apply
(
select 'firstname', firstname union all
select 'lastname', lastname
) c (columnname, value);
Див. SQL Fiddle with Demo .
Я прочитав MSDN, але не знайшов нічого, що пояснювало б причини для того, щоб змусити довжину на типі даних бути однаковою.
Яка логіка вимагає однакової довжини під час використання UNPIVOT?
