Gibt es eine bessere Option als Union All für Mehrfachauswahl aus derselben Zeile?

10

Beispielschema:

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,)

Gibt es eine Möglichkeit, Ergebnisse zu erzielen, die wie folgt angezeigt werden:

ID | OptionID | OptionName | OptionLName

Ich habe versucht, dies mit UNION ALL zu erreichen, aber dies bedeutet, dass ich in meinem Beispiel dreimal dieselbe Zeile durchlaufen habe. In meinem eigentlichen Problem muss ich dies zehnmal tun. Ich kann die Tabelle aufgrund von Legacy-Code nicht normalisieren. Gibt es eine Möglichkeit, die Basisreihe nur einmal zu durchlaufen?

JustinDoesWork
quelle

Antworten:

23

Sie können verwendet werden, CROSS APPLY ... VALUESum UNPIVOTmehrere Spalten

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

Der Ausführungsplan hierfür enthält einen Scan von Base. Der Plan ist in der Tat der gleiche wie für das 2005 kompatible Umschreiben, das verwendet wirdUNION 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)  

Aber ich nehme an, dass UNION ALLSie versucht haben, die mehrfachen Scans von zu vermeiden

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
quelle