¿Existe una mejor opción que Union All para múltiples selecciones de la misma fila?


10

Esquema de ejemplo:

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

¿Hay alguna manera de obtener resultados que se muestren como:

ID | OptionID | OptionName | OptionLName

He tratado de lograr esto usando UNION ALL, pero esto significa pasar la misma fila 3 veces en mi ejemplo, en mi problema real tengo que hacerlo 10 veces. No puedo normalizar la tabla debido al código heredado. ¿Hay alguna manera de pasar la fila Base una sola vez?

Respuestas:


23

Puedes usar CROSS APPLY ... VALUESpara UNPIVOTmúltiples columnas

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

El plan de ejecución para esto tiene un escaneo de Base. De hecho, el plan es el mismo que para la reescritura compatible de 2005 que utilizaUNION 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)  

Pero supongo que lo UNION ALLque intentabas evitar eran los múltiples escaneos de

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] 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.