基于声明的变量,是否可以在where子句中切换不等于和等于?
例如,如果变量@InState设置为true,则返回状态等于' CA'的所有地址,如果为false,则返回状态为<>的所有地址。 ' CA'
代码:
DECLARE @InState bit
SET @InState = 1
SELECT *
FROM dbo.tAddresses ADDR
WHERE ADDR.Status = 'A'
AND ADDR.State =
CASE WHEN @InState = 1
THEN
'CA'
ELSE
''
上面代码中的ELSE返回包括' CA'在内的每个州。我需要返回其他所有状态,而不是等于CA'
答案 0 :(得分:3)
我会尝试避免CASE
条款中的WHERE
语句,并尝试这样的事情;
测试数据;
DECLARE @Instate bit; SET @Instate = 1
CREATE TABLE #Addresses (ID int, State varchar(2), Status varchar(2))
INSERT INTO #Addresses (ID, State, Status)
VALUES
(1,'CA','A')
,(2,'NY','A')
,(3,'CA','A')
,(4,'NJ','A')
,(5,'FL','A')
,(6,'CA','A')
,(7,'ND','A')
查询
DECLARE @InState bit
SET @InState = 1
SELECT *
FROM #Addresses ADDR
WHERE ADDR.Status = 'A'
AND
(
(@InState = 1
AND ADDR.State = 'CA')
OR
(@InState <> 1
AND ADDR.State <> 'CA')
)
当@Instate = 1
时,这些就是结果;
ID State Status
1 CA A
3 CA A
6 CA A
当@Instate = 0
时,你得到了这个;
ID State Status
2 NY A
4 NJ A
5 FL A
7 ND A
WHERE
子句中的计算会使您的查询非SARGable
,从而导致您的表现下降;
答案 1 :(得分:1)
这是丑陋的,但它对我有用,
...
AND ADDR.State =
CASE WHEN @InState = 1 THEN 'CA' ElSE ADDR.State END
AND ADDR.State <>
CASE WHEN @InState = 0 THEN 'CA' ElSE ADDR.State END
答案 2 :(得分:1)
不是where子句但我认为它是可以攻击的
SELECT ADDR.*
FROM dbo.tAddresses ADDR
left join dbo.tAddresses ADDRin
on ADDRin.id = ADDR.id
and ADDRin.State = 'CA'
and @InState = 1
left join dbo.tAddresses ADDRout
on ADDRout.id = ADDR.id
and ADDRout.State <> 'CA'
and @InState = 0
WHERE ADDR.Status = 'A'
AND (ADDRin.id is not null or ADDRout.id is not null)
SELECT ADDR.*
FROM dbo.tAddresses ADDR
where ADDR.Status = 'A'
and ADDR.State = 'CA'
and @InState = 1
UNION ALL
SELECT ADDR.*
FROM dbo.tAddresses ADDR
where ADDR.Status = 'A'
and ADDR.State <> 'CA'
and @InState <> 1
答案 3 :(得分:1)
如何使用IF ELSE
IF (@Instate=1)
BEGIN
SELECT *
FROM dbo.tAddresses ADDR
WHERE ADDR.Status = 'A'
AND ADDR.State ='CA'
END
ELSE
BEGIN
SELECT *
FROM dbo.tAddresses ADDR
WHERE ADDR.Status = 'A'
AND ADDR.State <>'CA'
END
我知道它的程序性能不确定。但另一种选择。