case子句在where子句中的用法
Usage of case clause in where clause
我需要根据下拉列表值向存储过程添加过滤器
可用值为 0、1、2、3、4、5。 @TescilDurum 是我的参数。
0 = ALL
1 = TescilDurumId IN 4 OR 5
2 = t.ID IS NULL
3 = dncts.RegistrationCode IS NULL
4 = hsm.ID IS NULL AND dncts.RegistrationCode IS NULL IS NOT NULL
5 = hsm.ENSMRN IS NULL
到目前为止,我已经从互联网上的类似问题答案中尝试过此操作,但我不确定这样做是否正确。我不确定 "reverse logic" 是否是正确的方法。之后的order by也报错...
AND 1 =
CASE WHEN @TescilDurum = 1 AND t.TescilDurumId NOT IN (4,5) THEN 0
ELSE CASE WHEN @TescilDurum = 2 AND t.Id IS NOT NULL THEN 0
ELSE CASE WHEN @TescilDurum = 3 AND hsm.EnsMRN IS NOT NULL THEN 0
ELSE CASE WHEN @TescilDurum = 4 AND hsm.Id IS NOT NULL AND dncts.RegistrationCode IS NULL THEN 0
ELSE CASE WHEN @TescilDurum = 5 AND hsm.EnsMRN IS NOT NULL THEN 0
ELSE 1 END
你可以简化它:
WHERE
(CASE
WHEN @TescilDurum = 0 THEN 1
WHEN @TescilDurum = 1 AND TescilDurumId IN (4,5) THEN 1
WHEN @TescilDurum = 2 AND t.ID IS NULL THEN 1
WHEN @TescilDurum = 3 AND dncts.RegistrationCode IS NULL THEN 1
WHEN @TescilDurum = 4 AND hsm.ID IS NULL AND dncts.RegistrationCode IS NOT NULL THEN 1
WHEN @TescilDurum = 5 AND hsm.ENSMRN IS NULL THEN 1
ELSE NULL -- this is default and can be skipped if needed
END) = 1
编辑:
对于任何担心上面的查询总是 1 = 1
:
的人
CASE
有默认的 ELSE NULL
子句,所以当整个语句之前没有匹配项时,return NULL
和 NULL = 1 => NULL
.
DECLARE @v INT = 4;
SELECT 1
WHERE(CASE WHEN @v = 1 THEN 1
WHEN @v = 2 THEN 1
WHEN @v = 3 THEN 1
ELSE NULL -- this is default and can be skipped if needed
END) = 1
-- empty resultset
和:
CREATE TABLE #tab(ID INT, col VARCHAR(100));
INSERT INTO #tab
VALUES (1, 'aa'), (2, 'bbb'), (3, NULL), (4, 'aa');
-- DROP DOWN MENU
-- 1 all records
-- 2 only those which ID is in (2,3)
-- 3 only those which has col = 'aa'
-- 4 only those which has NULL value in col
DECLARE @variable INT = 3;
SELECT *
FROM #tab
WHERE
(
CASE WHEN @variable = 1 THEN 1
WHEN @variable = 2 AND ID IN (2,3) THEN 1
WHEN @variable = 3 AND col = 'aa' THEN 1
WHEN @variable = 4 AND col IS NULL THEN 1
ELSE NULL -- this is default and can be skipped if needed
END
) = 1
请记住,AND
存在复合条件,因此正确的行将被 returned。
我需要根据下拉列表值向存储过程添加过滤器
可用值为 0、1、2、3、4、5。 @TescilDurum 是我的参数。
0 = ALL
1 = TescilDurumId IN 4 OR 5
2 = t.ID IS NULL
3 = dncts.RegistrationCode IS NULL
4 = hsm.ID IS NULL AND dncts.RegistrationCode IS NULL IS NOT NULL
5 = hsm.ENSMRN IS NULL
到目前为止,我已经从互联网上的类似问题答案中尝试过此操作,但我不确定这样做是否正确。我不确定 "reverse logic" 是否是正确的方法。之后的order by也报错...
AND 1 =
CASE WHEN @TescilDurum = 1 AND t.TescilDurumId NOT IN (4,5) THEN 0
ELSE CASE WHEN @TescilDurum = 2 AND t.Id IS NOT NULL THEN 0
ELSE CASE WHEN @TescilDurum = 3 AND hsm.EnsMRN IS NOT NULL THEN 0
ELSE CASE WHEN @TescilDurum = 4 AND hsm.Id IS NOT NULL AND dncts.RegistrationCode IS NULL THEN 0
ELSE CASE WHEN @TescilDurum = 5 AND hsm.EnsMRN IS NOT NULL THEN 0
ELSE 1 END
你可以简化它:
WHERE
(CASE
WHEN @TescilDurum = 0 THEN 1
WHEN @TescilDurum = 1 AND TescilDurumId IN (4,5) THEN 1
WHEN @TescilDurum = 2 AND t.ID IS NULL THEN 1
WHEN @TescilDurum = 3 AND dncts.RegistrationCode IS NULL THEN 1
WHEN @TescilDurum = 4 AND hsm.ID IS NULL AND dncts.RegistrationCode IS NOT NULL THEN 1
WHEN @TescilDurum = 5 AND hsm.ENSMRN IS NULL THEN 1
ELSE NULL -- this is default and can be skipped if needed
END) = 1
编辑:
对于任何担心上面的查询总是 1 = 1
:
CASE
有默认的 ELSE NULL
子句,所以当整个语句之前没有匹配项时,return NULL
和 NULL = 1 => NULL
.
DECLARE @v INT = 4;
SELECT 1
WHERE(CASE WHEN @v = 1 THEN 1
WHEN @v = 2 THEN 1
WHEN @v = 3 THEN 1
ELSE NULL -- this is default and can be skipped if needed
END) = 1
-- empty resultset
和:
CREATE TABLE #tab(ID INT, col VARCHAR(100));
INSERT INTO #tab
VALUES (1, 'aa'), (2, 'bbb'), (3, NULL), (4, 'aa');
-- DROP DOWN MENU
-- 1 all records
-- 2 only those which ID is in (2,3)
-- 3 only those which has col = 'aa'
-- 4 only those which has NULL value in col
DECLARE @variable INT = 3;
SELECT *
FROM #tab
WHERE
(
CASE WHEN @variable = 1 THEN 1
WHEN @variable = 2 AND ID IN (2,3) THEN 1
WHEN @variable = 3 AND col = 'aa' THEN 1
WHEN @variable = 4 AND col IS NULL THEN 1
ELSE NULL -- this is default and can be skipped if needed
END
) = 1
请记住,AND
存在复合条件,因此正确的行将被 returned。