Ini seharusnya berhasil:
WITH Sales AS (
SELECT
S.SaleID,
S.SoldBy,
S.SalePrice,
S.Margin,
S.Date,
I.SalePrice,
I.Category
FROM
dbo.Sale S
INNER JOIN dbo.SaleItem I
ON S.SaleID = I.SaleID
)
SELECT *
FROM
Sales
PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
;
Atau bergantian:
SELECT
S.SaleID,
S.SoldBy,
S.SalePrice,
S.Margin,
S.Date,
I.Books,
I.Printing,
I.DVD
FROM
dbo.Sale S
INNER JOIN (
SELECT *
FROM
(SELECT SaleID, SalePrice, Category FROM dbo.SaleItem) I
PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
) I ON S.SaleID = I.SaleID
;
Ini memiliki kumpulan hasil yang sama dan mungkin sebenarnya diperlakukan sama oleh pengoptimal kueri, tetapi mungkin tidak. Perbedaan besar muncul saat Anda mulai menerapkan ketentuan pada Sale
tabel—Anda harus menguji dan melihat kueri mana yang berfungsi lebih baik.
Catatan:sangat penting saat menggunakan PIVOT
bahwa hanya kolom yang seharusnya menjadi bagian dari hasil keluaran yang tersedia. Inilah sebabnya mengapa dua kueri di atas memiliki subkueri tabel turunan tambahan (SELECT ...)
sehingga hanya kolom tertentu yang diekspos. Semua kolom yang tersedia dapat dilihat dengan PIVOT
yang tidak tercantum dalam ekspresi pivot secara implisit akan dikelompokkan dan disertakan dalam hasil akhir. Ini mungkin bukan yang Anda inginkan.
Bolehkah saya menyarankan, bagaimanapun, bahwa Anda melakukan pivoting di lapisan presentasi? Jika, misalnya, Anda menggunakan SSRS, cukup mudah untuk menggunakan kontrol matriks yang akan melakukan semua pivot untuk Anda. Itu yang terbaik, karena jika Anda menambahkan Category
baru , Anda tidak perlu mengubah semua kode SQL Anda!
Ada cara untuk menemukan nama kolom secara dinamis untuk pivot, tetapi ini melibatkan SQL dinamis. Saya juga tidak merekomendasikan itu sebagai cara terbaik, meskipun mungkin.
Cara lain yang bisa pekerjaannya adalah melakukan praproses kueri ini—artinya menyetel pemicu pada Category
tabel yang menulis ulang tampilan untuk memuat semua kategori yang ada yang ada. Ini memang memecahkan banyak masalah lain yang telah saya sebutkan, tetapi sekali lagi, menggunakan lapisan presentasi adalah yang terbaik.
Catatan :Jika nama kolom Anda (yang sebelumnya merupakan nilai) memiliki spasi, berupa angka atau dimulai dengan angka, atau bukan pengidentifikasi yang valid, Anda harus mengutipnya dengan tanda kurung siku seperti pada PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P
. Sebagai alternatif, Anda dapat mengubah nilai sebelum masuk ke PIVOT
bagian dari kueri untuk menambahkan beberapa huruf atau menghapus spasi, sehingga daftar kolom tidak perlu keluar. Untuk bacaan lebih lanjut tentang ini, lihat aturan untuk pengidentifikasi di SQL Server.