2011-05-25 47 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