将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');
如果我尝试取消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 Server 2005中引入UNPIVOT之前,我将使用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时要求相同长度的背后逻辑是什么?