TSQL - использовать производный столбец выбора в предложении Where - PullRequest
11 голосов
/ 19 января 2010

Есть ли способ в 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").

Ответы [ 6 ]

20 голосов
/ 19 января 2010
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
5 голосов
/ 19 января 2010

Это хорошее место для использования 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 
3 голосов
/ 19 января 2010

Другой вариант - реализовать оператор 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 
2 голосов
/ 19 января 2010

Я согласен с AlexKuznetsov по этому вопросу, но я бы также добавил, что если ваш запрос (независимо от того, насколько он более сложный) ограничен в случаях предложения WHERE, которые существуют вCASE, тогда эти CASE s никогда не будут возвращены и не должны выбираться в первую очередь.

Например, вы устанавливаете d в '6', где aравен '2', затем ограничивается WHERE d = 6, поэтому вы можете вместо этого сделать:

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

Это вернет те же результаты в более оптимизированном и чистом виде.Вот почему, ИМХО, нет смысла ссылаться на производный столбец.

2 голосов
/ 19 января 2010

Сделайте ваш опубликованный запрос подзапросом и выберите из него, где d = 6. Насколько я знаю, нет возможности ссылаться на производный столбец в том же запросе.

0 голосов
/ 28 января 2012

Альтернативным методом является использование 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...