Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL server bergabung dengan tabel dan pivot

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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hasil SQL dinamis menjadi tabel temp dalam prosedur SQL Stored

  2. Kembalikan baris di mana ID berada dalam string yang dipisahkan titik koma dari subquery MSSQL

  3. Mengapa tidak SET XACT_ABORT ON perilaku default?

  4. Harus mendeklarasikan variabel skalar @Id?

  5. Buat Kolom Terhitung menggunakan data dari tabel lain