2011-05-25 34 views
2

我想知道在SQL Server 2005中是否可以實現以下功能。列A和B在我的實際存儲過程中使用其他case語句進行計算。我不想在不必要的情況下重複其他字段。如果這在語法上不可行,還有其他想法?在sql語句中使用同一語句中的其他選定列的case語句

SELECT A, B, CASE WHEN column1='1' THEN A ELSE B END Col1. 

根據請求提供的實際查詢的修改版本。 CTE在這個模型中似乎很難。 WANNABE是我希望在sub select語句中完成的列。

SELECT 1 AS Region, 'Test', 
     CAST(Work AS NUMERIC(18,2)) Work, 
     Work + 2 AS Work2, 
     WANNABE 

     FROM 
     (
      SELECT 
       ROW_NUMBER() OVER(PARTITION BY G.Value, C.C, FR.Mod1 ORDER BY FR.Date DESC, FG.Date DESC, FC.Date DESC) ROW, 
       CASE WHEN COALESCE(FR.Mod1, '') = '' THEN '' ELSE FR.Mod1 END Mod1, 

       CASE WHEN @var1=1 AND @var2 = 1 THEN FR.Col1 * G.Value 
        WHEN @var1=1 AND @var2 = 0 THEN FP.Col1 * G.Value END Work, 

       CASE WHEN 1=1 THEN Work ELSE 1 END WANNABE, 

       (
        SELECT Col3 
        FROM Table2 
        WHERE c = FR.Value 
       ) AS Custom 

      FROM MainTable FR 
      JOIN @C C ON FR.Col2 = C.Col2 
      LEFT JOIN Function1(@VersionDate) cv ON cv.Code = C.Code  
      LEFT JOIN Function2(@VersionDate) hv ON hv.Code = C.Code  
      LEFT JOIN @G G ON 1 = 1 
      LEFT JOIN SubTable1 FG ON FG.Number = G.Value, 2 AND FG.Date = @VersionDate 
      LEFT JOIN SubTable2 FO ON FO.Number = G.Value 
       AND FO.Date = @VersionDate AND FO.Code = FR.Code AND FR.Mod1 = FO.Mod1 
      LEFT JOIN SubTable3 FP ON FP.Code = FR.Code AND FP.VersionDate = @Versiondate 
      AND CASE WHEN DATALENGTH(FR.Mod1) = 0 THEN '00' ELSE FR.Mod1 END = CASE WHEN DATALENGTH(FP.Mod1) = 0 THEN '00' ELSE FP.Mod1 END 
      LEFT JOIN SubTable4 FC ON FC.Date = @VersionDate 
      WHERE FR.Date = @VersionDate 
     ) x 
     WHERE x.Row = 1 
     AND RTRIM(LTRIM(x.Col1)) IN ('', '2') 

回答

3

您可以在CTE中定義A,B列別名,然後在外部選擇中引用它們。

;WITH CTE AS 
(
SELECT CASE ... END AS A, 
     CASE ... END AS B, 
     column1 
FROM your_table 
) 
SELECT A, 
     B, 
     CASE WHEN column1='1' THEN A ELSE B END Col1 
FROM CTE 

類似的,你也可以在CROSS APPLY中定義它們,有時候會少些冗長。 一個愚蠢的例子,是想說明語法

SELECT A, 
     B, 
     CASE WHEN type='P' THEN A ELSE B END Col1 
FROM master..spt_values 
CROSS APPLY (SELECT CASE WHEN number %2 = 1 THEN 1 END, 
        CASE WHEN number %2 = 0 THEN 0 END) T(A,B) 

追隨你的更新,你可以用一個CTE和鳥巢的CTE更換派生表如下

;WITH x as 
(
       SELECT 
        ROW_NUMBER() OVER(PARTITION BY G.Value, C.Code, FR.Mod1 ORDER BY FR.Date DESC, FG.Date DESC, FC.Date DESC) ROW, 
...<snip>     
       WHERE FR.Date = @VersionDate 
), 
x2 As 
(
SELECT *, 
     CASE WHEN 1=1 THEN Work ELSE 1 END WANNABE 
FROM x 
) 
    SELECT 1 AS Region, 'Test', 
      CAST(Work AS NUMERIC(18,2)) Work, 
      Work + 2 AS Work2, 
      WANNABE 
      FROM x2 
      WHERE x2.Row = 1 
      AND RTRIM(LTRIM(x2.Col1)) IN ('', '2') 
+0

這很有趣。我總是忘記CTE。讓我試試看,並會回來。 – 2011-05-25 17:01:51

+0

不幸的是我的查詢是在一個子選擇..類似select * from(SELECT ROW_NUMBER()OVER(PARTITION BY條件)行,A,B等..)x WHERE x.row = 1。我不認爲我可以在子選擇中使用CTE。 – 2011-05-25 17:12:05

+0

你可以發佈你的實際查詢到問題嗎?這不應該有任何區別。 – 2011-05-25 17:13:23

0

啊這是更多鈔票,但如何爲所有你的SQL語句?您可以在使用select語句時使用case語句。 類似這樣的東西

SELECT SUM((CASE WHEN column1='1' THEN 10 ELSE 0 END)) AS A, SUM((CASE WHEN column1='2' THEN 10 ELSE 0 END)) AS B 
FROM YourTable 
+0

不知道我是否想在這裏使用SUM。它比這更復雜一點。問題中添加了詳細的查詢。 – 2011-05-25 17:57:24