2012-04-24 33 views
0

如何使以下T-SQL語句合法?我可以複製爲每個CASE選項設置@Type變量的子查詢,但我寧願只執行一次子查詢。可能嗎?在設置它的相同SELECT語句中使用SQL變量進行比較

SELECT 
     @Type = (SELECT CustomerType FROM dbo.Customers WHERE CustomerId = (SELECT CustomerId FROM dbo.CustomerCategories WHERE CatId= @CatId)), 
     CASE 
     WHEN @Type = 'Consumer'THEN dbo.Products.FriendlyName 
     WHEN @Type = 'Company' THEN dbo.Products.BusinessName 
     WHEN @Type IS NULL THEN dbo.Products.FriendlyName 
     WHEN @Type = '' THEN dbo.Products.FriendlyName 
     END Product, 
     ... 
FROM 
     Products 
INNER JOIN 
     Category 
... 

編輯:修改我的例子更具體的......現在得跑......會回來的明天...簽署過短的遺憾,但不得不拿起孩子:d將檢查明天回來。謝謝!!

澄清:我不能分開這兩個:在子查詢的where-clasue中,我需要引用表中的主要查詢的join stmt中使用的列。如果我將它們分開,那麼@Type將失去相關性。

+0

你需要更具體的一部分。 – 2012-04-24 19:53:20

+0

你仍然太模糊。請告訴我們你需要做什麼,而不是告訴我們你認爲你需要做什麼。我認爲這裏有一個關於查詢和變量如何工作的根本缺失的鏈接,但是如果您向我們展示示例數據和期望的結果,那麼我們是非常聰明的人,並且可能想出如何實現您所追求的內容。 – 2012-04-24 20:03:22

+0

如果您指定您正在使用的SQL Server的版本,這也很有用! – 2012-04-24 20:07:39

回答

4

爲什麼不把它分成兩個操作?你認爲你通過試圖將他們變成一個單獨的陳述而獲得什麼?

SELECT @Type = (subquery); 

SELECT CASE WHEN @type = 'Consumer'... 

冒着低沉的聲音,你真的需要變量嗎?爲什麼不:

SELECT CASE WHEN col_form_subquery = 'Consumer' THEN ... 
    END Product 
FROM (<subquery>) AS x; 

用這種形式,你需要決定是否要給變量賦值或檢索結果。

您也可以拉多個變量,例如,

SELECT @Col1 = Col1, @Col2 = Col2 
    FROM (<subquery>) AS x; 

-- then refer to those variables in your other query: 

SELECT *, @Col1, @Col2 FROM dbo.Products WHERE Col1 = @Col2; 

但這都是猜測,因爲你沒有分享足夠的細節。

編輯好了,現在我們有一個真正的查詢,可以瞭解一個好一點你以後,讓我們看看,如果我們可以給你寫一個新的版本。我假設你只是試圖存儲@Type變量,所以你可以在查詢中重用它,並且你並沒有試圖在那裏存儲一個值,以便在以後使用(在這個查詢之後)。

SELECT CASE 
     WHEN c.CustomerType = 'Company' THEN p.BusinessName 
     WHEN COALESCE(c.CustomerType, '') IN ('Consumer', '') THEN p.FriendlyName 
    END 
    --, other columns 
FROM dbo.Products AS p 
INNER JOIN dbo.Category AS cat 
    ON p.CatId = cat.CatId 
INNER JOIN dbo.CustomerCategories AS ccat 
    ON ccat.CatId = cat.CatId 
INNER JOIN dbo.Customers AS c 
    ON c.CustomerId = ccat.CustomerId 
WHERE cat.CategoryId = @CatId; 

一些注意事項:

  • 我不知道爲什麼你以爲子查詢處理這個正確的方式。通常,建立適當的連接並讓SQL Server優化整個查詢,而不是試圖變得聰明,並且優化個別子查詢,這很大程度上獨立於主查詢,這對於其他開發者來說更​​好(也更清楚)。正確的連接將有助於消除先前的行,否則,通過子查詢可能會實現 - 只能被丟棄。信任SQL Server來完成它的工作,在這種情況下,它的工作是跨多個表執行聯接。
  • 如果SELECT不需要顯示類別名稱,則可能不需要連接到dbo.Category。如果是這樣,則更改where子句並刪除該連接(改爲連接到CusomterCategories)。
  • 如果您已涵蓋所有可能的情況,則可以將第二種情況更改爲簡單的ELSE。
  • 我對產品和類別之間的聯繫做了一個假設(爲什麼類別不像其他類型那樣是複數?)。如果這不是,請填寫我們。
+0

不能將它們分開。需要他們一起進行設置操作。 – Laguna 2012-04-24 19:46:50

+0

你能解釋一下你認爲「set-operation」的含義嗎? – 2012-04-24 19:55:55

+0

大聲笑(我在嘲笑自己)...基本上我的意思是在子查詢的where-clasue中,我需要引用主表中用於主查詢的表中的列連接...我知道它可能還不清楚請讓我知道任何我可以澄清的細節。謝謝! – Laguna 2012-04-24 19:59:59

4

你不能這樣做,你會得到以下錯誤

一個值賦給變量不能與數據檢索操作結合

的SELECT語句。

將二者分開,然後返回變量作爲select語句

+0

不能將它們分開。需要他們一起進行設置操作。 – Laguna 2012-04-24 19:47:08

+2

您無法爲變量賦值並同時返回結果集 – SQLMenace 2012-04-24 19:51:06

+0

需要了解的內容。謝謝。有沒有辦法避免多次執行子查詢? – Laguna 2012-04-24 19:52:18

相關問題