Застосовуючи 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?