同じ行からの複数選択に対して、Union Allよりも優れたオプションはありますか?


10

スキーマの例:

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

次のように表示される結果を取得する方法はありますか?

ID | OptionID | OptionName | OptionLName

私はUNION ALLを使用してこれを達成しようとしましたが、これは私の例では同じ行を3回処理することを意味し、実際の問題では10回実行する必要があります。レガシーコードのため、テーブルを正規化できません。ベース行を一度だけ超える方法はありますか?

回答:


23

あなたは使用することができますCROSS APPLY ... VALUESUNPIVOT、複数の列

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

この実行プランには、1回のスキャンがありBaseます。計画は実際に使用する2005互換性のある書き換えと同じですUNION 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)  

しかし、UNION ALLあなたが避けようとしていたのは、複数回のスキャンだったと思います

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] 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.