Apakah ada opsi yang lebih baik daripada Union All untuk beberapa pilihan dari baris yang sama?

10

Contoh Skema:

CREATE TABLE [dbo].[Base](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Option1ID] [int] NULL,
[Option2ID] [int] NULL,
[Option3ID] [int] NULL,
[Option1Name] [varchar] NULL,
[Option2Name] [varchar] NULL,
[Option3Name] [varchar] NULL,
[Option1LName] [varchar] NULL,
[Option2LName] [varchar] NULL,
[Option3LName] [varchar] NULL,)

Apakah ada cara untuk mendapatkan hasil yang muncul seperti:

ID | OptionID | OptionName | OptionLName

Saya telah mencoba untuk mencapai ini menggunakan UNION ALL tetapi ini berarti melewati baris yang sama 3 kali dalam contoh saya, dalam masalah saya yang sebenarnya saya harus melakukannya 10 kali. Saya tidak bisa menormalkan tabel karena kode lawas. Apakah ada cara untuk hanya melewati baris Base sekali?

JustinDoesWork
sumber

Jawaban:

23

Anda dapat menggunakan CROSS APPLY ... VALUESuntuk UNPIVOTbeberapa kolom

SELECT ID,
       OptionID,
       OptionName,
       OptionLName
FROM   [dbo].[Base]
       CROSS APPLY (VALUES([Option1ID], [Option1Name], [Option1LName]),
                          ([Option2ID], [Option2Name], [Option2LName]),
                          ([Option3ID], [Option3Name], [Option3LName])) 
                     V( OptionID, OptionName, OptionLName) 

Rencana pelaksanaan untuk ini memiliki satu pemindaian Base. Rencananya sebenarnya sama dengan penulisan ulang kompatibel 2005 yang menggunakanUNION ALL

SELECT ID,
       OptionID,
       OptionName,
       OptionLName
FROM   [dbo].[Base]
       CROSS APPLY (SELECT [Option1ID], [Option1Name], [Option1LName] UNION ALL
                    SELECT [Option2ID], [Option2Name], [Option2LName] UNION ALL
                    SELECT [Option3ID], [Option3Name], [Option3LName]) 
                     V( OptionID, OptionName, OptionLName)  

Tapi saya kira UNION ALLAnda mencoba menghindari adalah beberapa scan

SELECT ID,
       [Option1ID],
       [Option1Name],
       [Option1LName]
FROM   [dbo].[Base]
UNION ALL
SELECT ID,
       [Option2ID],
       [Option2Name],
       [Option2LName]
FROM   [dbo].[Base]
UNION ALL
SELECT ID,
       [Option3ID],
       [Option3Name],
       [Option3LName]
FROM   [dbo].[Base] 
Martin Smith
sumber