Reputation: 47124
Is there a way in TSQL to do something like this:
select a,b,c,
case
when a=1 then 5
when a=2 then 6
end as d
from some_table
where d=6
The actual case statement is really complex, so I'm trying to avoid repeating it in the where clause? Are there any tricks to do this?
(I think there's a trick in MySQL to use "having d=6").
Upvotes: 13
Views: 18466
Reputation: 17090
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
Upvotes: 25
Reputation: 65167
An alternative method to this is to use 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
Upvotes: 0
Reputation: 340
Another option is to implement your case
statement as a function. Especially good for conversion or calculation issues. What's nice about functions is that the 'business' logic is in one place and can easily be reused in other queries.
-- 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
Upvotes: 3
Reputation: 5932
I'm going to agree with AlexKuznetsov on this one, but I would also add that if your query is (no matter how much more complex) limiting in the WHERE
clause cases that exist in the CASE
, then those CASE
s will never be returned and shouldn't be selected in the first place.
For example, you're setting d
to '6' where a
is '2', then limiting to WHERE d = 6
, so you could instead do:
SELECT a,b,c,
6 AS d
FROM some_table
WHERE a = 2
This will return the same results in a more optimized and clean fashion. This is why, IMHO, there's no point in being able to reference a derived column.
Upvotes: 2
Reputation: 171431
This is a good place to use CTEs, e.g.:
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
Upvotes: 8
Reputation: 1805
Make your posted query a sub-query and select from it where d = 6. As far as I know there is no way to reference a derived column in the same query.
Upvotes: 2