Saat menerapkan UNPIVOT
fungsi ke data yang tidak dinormalisasi, SQL Server mensyaratkan bahwa tipe data dan panjangnya harus sama. Saya mengerti mengapa datatype harus sama tetapi mengapa UNPIVOT membutuhkan panjangnya harus sama?
Katakanlah saya memiliki data sampel berikut yang harus saya batalkan 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');
Jika saya mencoba untuk UNPIVOT Firstname
dan Lastname
kolom yang mirip dengan:
select PersonId, ColumnName, Value
from People
unpivot
(
Value
FOR ColumnName in (FirstName, LastName)
) unpiv;
SQL Server menghasilkan kesalahan:
Msg 8167, Level 16, State 1, Line 6
Jenis kolom "Nama belakang" bertentangan dengan jenis kolom lain yang ditentukan dalam daftar UNPIVOT.
Untuk menyelesaikan kesalahan, kita harus menggunakan subquery untuk terlebih dahulu membuat Lastname
kolom dengan panjang yang sama seperti 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;
Lihat SQL Fiddle dengan Demo
Sebelum UNPIVOT diperkenalkan di SQL Server 2005, saya akan menggunakan SELECT
with UNION ALL
untuk membatalkan penguncian firstname
/ lastname
kolom dan kueri akan berjalan tanpa perlu mengonversi kolom ke panjang yang sama:
select personid, 'firstname' ColumnName, firstname value
from People
union all
select personid, 'LastName', LastName
from People;
Lihat SQL Fiddle dengan Demo .
Kami juga dapat berhasil mem-undivot data menggunakan CROSS APPLY
tanpa memiliki panjang yang sama pada tipe data:
select PersonId, columnname, value
from People
cross apply
(
select 'firstname', firstname union all
select 'lastname', lastname
) c (columnname, value);
Lihat SQL Fiddle dengan Demo .
Saya telah membaca MSDN tapi saya tidak menemukan penjelasan alasan untuk memaksa panjang pada datatype menjadi sama.
Apa logika di balik yang membutuhkan panjang yang sama saat menggunakan UNPIVOT?