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
列「Lastname」のタイプは、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をご覧ください
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 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を使用する際に同じ長さを要求する理由は何ですか?