2016-08-12 23 views
0

我有一個關於SQL的基礎知識。但我可能需要一些先進的幫助解決這個問題。SQL在同一列和表中的單個SELECT中設置不同的變量,不同的條件

我正在開發一個執行不同的SQL準備語句的API,現在我正試圖優化這些查詢。

目前我一個準備好的聲明中有來自同一個表中選擇多個SELECT語句,但每個人都有自己的條件,例如:

DECLARE 
    @DESCRIPTION_1 NVARCHAR(200) 
, @DESCRIPTION_2 NVARCHAR(200) 
, @DESCRIPTION_3 NVARCHAR(200) 

SELECT @DESCRIPTION_1 = [DESCRIPTION] FROM [Objectives] WHERE [OBJECTIVE_ID] = '4E2DEA7B-025A-4958-8696-2D13EDD3E08E'; 
SELECT @DESCRIPTION_2 = [DESCRIPTION] FROM [Objectives] WHERE [OBJECTIVE_ID] = '81B9B7E5-A833-4C5A-9B73-CBACFB055404'; 
SELECT @DESCRIPTION_3 = [DESCRIPTION] FROM [Objectives] WHERE [OBJECTIVE_ID] = 'A065CF91-01C9-41A8-A326-A00402329833'; 

*這僅是我的查詢的濃縮版。原來這個樣子的:

SELECT 
    @OBJECTIVE_1_DESCRIPTION = [dbo].[Objectives].[OBJECTIVE_DESCRIPTION] 
, @OBJ1_LVL = [dbo].[Objectives].[OBJECTIVE_LEVEL] 
, @OBJ1_TARGET = [dbo].[Objectives].[OBJECTIVE_COMPETION_COUNT] 
, @REWARD_1_CODE = [dbo].[Objectives].[OBJECTIVE_REWARD] 
FROM [dbo].[Objectives] 
WHERE [dbo].[Objectives].[OBJECTIVE_ID] = @OBJECTIVE1_ID; 

有沒有什麼辦法可以結合本成一個單一的SELECT語句?

+0

爲什麼不選擇'SELECT ... WHERE OBJECTIVE_ID IN ...'? –

+0

@PanagiotisKanavos,那隻會讓所有3個DESCRIPTIONS具有相同的值。每個人都需要有一個獨特的價值。 –

+0

你會得到3行每一個單一的值。您可以將其存儲在表值字段中,但使用查詢來獲得最終結果會更快,而不是將中間結果存儲在變量中 –

回答

1
DECLARE 
    @DESCRIPTION_1 NVARCHAR(200) 
, @DESCRIPTION_2 NVARCHAR(200) 
, @DESCRIPTION_3 NVARCHAR(200) 

Select @DESCRIPTION_1 = max(case when [OBJECTIVE_ID] = '4E2DEA7B-025A-4958-8696-2D13EDD3E08E' then [DESCRIPTION] else null end) 
     ,@DESCRIPTION_2 = max(case when [OBJECTIVE_ID] = '81B9B7E5-A833-4C5A-9B73-CBACFB055404' then [DESCRIPTION] else null end)  
     ,@DESCRIPTION_3 = max(case when [OBJECTIVE_ID] = 'A065CF91-01C9-41A8-A326-A00402329833' then [DESCRIPTION] else null end)  
FROM [Objectives] 
Where [OBJECTIVE_ID] in ('4E2DEA7B-025A-4958-8696-2D13EDD3E08E','81B9B7E5-A833-4C5A-9B73-CBACFB055404','A065CF91-01C9-41A8-A326-A00402329833') 

我也將宣佈3 @ OBJECTIVE_ID的減少文本和冗餘

另外,WHERE是可選的,如果你有一個小桌子,將其刪除

+0

謝謝你的建議。這只是我的查詢的精簡版本。原始的在每個select語句中設置8個變量,並將每個ID分配給@OBJECTIVE_ID。 –

+0

這不僅僅是一個精簡版。該問題中的查詢對數據庫執行3個不同的查詢。這是一個單一的查詢。 –

+0

@PanagiotisKanavos這就是我的想法,但顯然DévanCoetzee沒有看到這種方式 –

0

爲什麼不立即將它們用子選擇?

DECLARE @DESCRIPTION_1 NVARCHAR(200)=(SELECT [DESCRIPTION] FROM [Objectives] WHERE [OBJECTIVE_ID] = '4E2DEA7B-025A-4958-8696-2D13EDD3E08E'); 
DECLARE @DESCRIPTION_2 NVARCHAR(200)=(SELECT [DESCRIPTION] FROM [Objectives] WHERE [OBJECTIVE_ID] = '81B9B7E5-A833-4C5A-9B73-CBACFB055404'); 
DECLARE @DESCRIPTION_3 NVARCHAR(200)=(SELECT [DESCRIPTION] FROM [Objectives] WHERE [OBJECTIVE_ID] = 'A065CF91-01C9-41A8-A326-A00402329833'); 

假設有你的OBJECTIVE_ID索引,這應該是非常快的,以及...

+0

我有3個SELECT語句設置了18個變量,我想減少SELECT語句的數量。 –

+0

@DévanCoetzee索引每個子選擇閃電般快。我寧願質疑整個方法:*爲什麼要將這些值存儲在變量中?*任何其他解決方案 - 很可能 - 會採用相同的時間或甚至更長的時間...您至少需要爲每個值選擇一個值在你的WHERE裏。如果這是你目前的做法,這應該沒問題! – Shnugo

+0

我將這些變量插入到不同的表中並返回它們。謝謝你的建議,我真的很感激。我試圖擠出每一點的效率,我可以。 –

-1

使用UNION:

SELECT 
    @Objective1_Id Objective_Id, 
    @OBJECTIVE_1_DESCRIPTION = [dbo].[Objectives].[OBJECTIVE_DESCRIPTION] 
, @OBJ1_LVL = [dbo].[Objectives].[OBJECTIVE_LEVEL] 
, @OBJ1_TARGET = [dbo].[Objectives].[OBJECTIVE_COMPETION_COUNT] 
, @REWARD_1_CODE = [dbo].[Objectives].[OBJECTIVE_REWARD] 
FROM [dbo].[Objectives] 
WHERE [dbo].[Objectives].[OBJECTIVE_ID] = @OBJECTIVE1_ID 
UNION 
SELECT 
    @Objective2_Id, 
    @OBJECTIVE_1_DESCRIPTION = [dbo].[Objectives].[OBJECTIVE_DESCRIPTION] 
, @OBJ1_LVL = [dbo].[Objectives].[OBJECTIVE_LEVEL] 
, @OBJ1_TARGET = [dbo].[Objectives].[OBJECTIVE_COMPETION_COUNT] 
, @REWARD_1_CODE = [dbo].[Objectives].[OBJECTIVE_REWARD] 
FROM [dbo].[Objectives] 
WHERE [dbo].[Objectives].[OBJECTIVE_ID] = @OBJECTIVE2_ID 
UNION 
SELECT 
    @Objective3_Id, 
    @OBJECTIVE_1_DESCRIPTION = [dbo].[Objectives].[OBJECTIVE_DESCRIPTION] 
, @OBJ1_LVL = [dbo].[Objectives].[OBJECTIVE_LEVEL] 
, @OBJ1_TARGET = [dbo].[Objectives].[OBJECTIVE_COMPETION_COUNT] 
, @REWARD_1_CODE = [dbo].[Objectives].[OBJECTIVE_REWARD] 
FROM [dbo].[Objectives] 
WHERE [dbo].[Objectives].[OBJECTIVE_ID] = @OBJECTIVE3_ID; 

假設所有@ObjectiveX_id存在的行,你有一個查詢將返回3行,每行包含它所涉及的objective_id。

+0

你試過這個嗎?這是行不通的... – Shnugo

+0

由於我沒有他的桌子,我沒有。爲什麼它不工作? –

+0

這與實際數據無關......只是語法。試試這個'DECLARE @ v1 INT,@ v2 INT; SELECT @ v1 = 1;/* UNION ALL */SELECT @ v2 = 2; SELECT @ v1,@ v2;'然後拿掉';'並取消註釋'UNION ALL' ... Btw:如果它工作,它會將值寫入相同的變量(全部爲1)。 Btw2:與三個單獨的陳述相同的優點是什麼? – Shnugo

0

好的,如果我可以再拍一次。如你所知,SQL Server不支持數組,或動態創建變量(無動態SQL)

我應該添加,IDENTITY保持適當的順序,以防萬一它很重要。

Declare @KeyID Table (Key_PS int identity,Key_Value varchar(100)) 
Insert Into @KeyID values (@OBJECTIVE1_ID),(@OBJECTIVE2_ID),(@OBJECTIVE3_ID) 

SELECT @OBJECTIVE_1_DESCRIPTION = max(IIF(Key_PS=1 ,[OBJECTIVE_DESCRIPTION],null)) 
    , @OBJ1_LVL     = max(IIF(Key_PS=1 ,[OBJECTIVE_LEVEL],null)) 
    , @OBJ1_TARGET    = max(IIF(Key_PS=1 ,[OBJECTIVE_COMPETION_COUNT],null)) 
    , @REWARD_1_CODE   = max(IIF(Key_PS=1 ,[OBJECTIVE_REWARD],null)) 
    --... [2 - 17] ... -- 
    , @OBJECTIVE_18_DESCRIPTION = max(IIF(Key_PS=18,[OBJECTIVE_DESCRIPTION],null)) 
    , @OBJ18_LVL    = max(IIF(Key_PS=18,[OBJECTIVE_LEVEL],null)) 
    , @OBJ18_TARGET    = max(IIF(Key_PS=18,[OBJECTIVE_COMPETION_COUNT],null)) 
    , @REWARD_18_CODE   = max(IIF(Key_PS=18,[OBJECTIVE_REWARD],null)) 
FROM (Select B.*,A.* 
     From [dbo].[Objectives] 
     Join @KeyID B on (A.OBJECTIVE_ID=B.Key_Value) 
    ) A 
相關問題