12

TSQL 中有没有办法做这样的事情:

select a,b,c,
case 
  when a=1 then 5
  when a=2 then 6
end as d
from some_table
where d=6

实际的 case 语句非常复杂,所以我试图避免在 where 子句中重复它?有什么技巧可以做到这一点吗?

(我认为 MySQL 中有一个使用“具有 d=6”的技巧)。

4

6 回答 6

23
select
    a, b, c
from (
    select
        a, b, c,
        case 
          when a=1 then 5
          when a=2 then 6
        end as d
    from some_table
) as t
where d=6
于 2010-01-19T20:09:25.150 回答
7

这是使用CTE的好地方,例如:

WITH MassagedData (a, b, c, d) AS
(
    select a, b, c,
        case 
          when a=1 then 5
          when a=2 then 6
        end as d
    from some_table
)

SELECT a,b,c
FROM MassagedData
where d=6 
于 2010-01-19T20:15:01.113 回答
3

另一种选择是将您的case语句实现为函数。特别适用于转换或计算问题。函数的好处是“业务”逻辑在一个地方,可以很容易地在其他查询中重用。

-- sample code not tested

CREATE FUNCTION dbo.fn_MyConvertA(
    -- Add the parameters for the function here
    @a int
)
RETURNS int -- for example
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar as int

-- Add the T-SQL statements to compute the return value here
set @ResultVar = case when @a = 1 then 5 when @a = 2 then 6 else 10 end

-- Return the result of the function
RETURN @ResultVar

END
GO

-- now you case write your query
select a,b,c,  dbo.fn_MyConvertA(a) as d
from some_table          
where dbo.fn_MyConvertA(a)=6 
于 2010-01-19T20:48:13.423 回答
2

使您发布的查询成为子查询并从中选择 d = 6。据我所知,无法在同一查询中引用派生列。

于 2010-01-19T20:10:28.723 回答
2

我将同意AlexKuznetsov在这一点上的观点,但我还要补充一点,如果您的查询(无论复杂得多)限制在WHERE中存在的子句情况下CASE,那么那些CASEs 将永远不会被返回并且应该t 首先被选中。

例如,您设置d为“6”,其中a“2”是“2”,然后限制为WHERE d = 6,因此您可以改为:

SELECT a,b,c,
    6 AS d
FROM some_table
WHERE a = 2

这将以更优化和更干净的方式返回相同的结果。这就是为什么,恕我直言,能够引用派生列是没有意义的。

于 2010-01-19T20:17:02.980 回答
0

另一种方法是使用CROSS APPLY

select a,b,c,
from some_table
CROSS APPLY (SELECT case 
                    when a=1 then 5
                    when a=2 then 6
                    end) CxA(d)
where d=6
于 2012-01-27T21:27:59.500 回答