下面的简化代码不会返回field1中带NULL的行(与field2,field3相同)。我可以在等号后更改任何内容,如果需要可以更改等号,但是WHERE field1
之前的所有内容都应保持不变。
如何在同一案例中提取is null
行?实际查询很大并且已经在三个begin..end
块中,所以我真的不想通过将3个块乘以更多来进一步复杂化。对于(ALL)我想要所有行和对于(x)我希望特定值加上空值和数据将等于变量中的任何行。
declare @var1 varchar(100)
declare @var2 varchar(100)
declare @var3 varchar(100)
set @var1 = '(ALL)'
set @var2 = '(x)'
set @var3 = 'data'
SELECT *
FROM table
WHERE
field1 = CASE @var1 WHEN '(ALL)' THEN field1
WHEN '(x)' THEN (x & nulls)
ELSE @var1
END
AND field2 = CASE @var2 WHEN '(ALL)' THEN field2
WHEN '(x)' THEN (x & nulls)
ELSE @var2
END
AND field3 = CASE @var3 WHEN '(ALL)' THEN field3
WHEN '(x)' THEN (x & nulls)
ELSE @var3
END
我真的需要说明整个WHERE行,有没有办法做到这一点?
WHERE CASE @var1 WHEN '(x)' THEN field1 = @var1 or field1 is null
编辑:我开发了一个有效的解决方案!问题是WHERE子句需要一个赋值,它不能只是一个直接的CASE,所以我们将实现一个伪真/假赋值。对@ var2 / field2和@ var3 / field3使用类似的代码。希望此解决方案能够在未来帮助其他人。谢谢你们这个伟大的网站!
SELECT * FROM table WHERE
1 = CASE WHEN @var1 = '(ALL)' THEN 1
WHEN @var1 = '(x)' AND (field1 = @var1 OR field1 IS NULL) THEN 1
WHEN @var1 = field1 THEN 1
ELSE 0 END
编辑:如果你真的想要压缩它:( field1 = @ var1由最后的WHEN条件处理)
SELECT * FROM table WHERE
1 = CASE WHEN @var1 = '(ALL)' THEN 1
WHEN @var1 = '(x)' AND field1 IS NULL THEN 1
WHEN @var1 = field1 THEN 1
ELSE 0 END
答案 0 :(得分:0)
将WHERE子句重写为以下内容:
WHERE
(@var1 in ('(ALL)','(x)') OR field1 = @var1)
AND (@var2 in ('(ALL)','(x)') OR field2 = @var2)
AND (@var3 in ('(ALL)','(x)') OR field3 = @var3)
答案 1 :(得分:0)
根据之前的答案和评论,您正在寻找类似的内容:
SELECT *
FROM table
WHERE
(@var1 = '(ALL)' OR (@var1 ='(x)' AND IsNull(field1, '(x)') = @var1) OR field1 = @var1)
AND (@var2 = '(ALL)' OR (@var2 ='(x)' AND IsNull(field2, '(x)') = @var2) OR field2 = @var2)
AND (@var3 = '(ALL)' OR (@var3 ='(x)' AND IsNull(field3, '(x)') = @var3) OR field3 = @var3)
AND ...
如果给定的'x'可以是任何字符序列,您将需要这样的内容:
SELECT *
FROM table
WHERE
(@var1 = '(ALL)' OR (@var1 like '(%)' AND IsNull(field1, SUBSTRING(@var1,2,LEN(@var1)-2)) = SUBSTRING(@var1,2,LEN(@var1)-2)) OR field1 = @var1)
AND (@var2 = '(ALL)' OR (@var2 like '(%)' AND IsNull(field2, SUBSTRING(@var2,2,LEN(@var2)-2)) = SUBSTRING(@var2,2,LEN(@var2)-2)) OR field2 = @var2)
AND (@var3 = '(ALL)' OR (@var3 like '(%)' AND IsNull(field3,SUBSTRING(@var3,2,LEN(@var3)-2)) = SUBSTRING(@var3,2,LEN(@var3)-2)) OR field3 = @var3)
为了结束我的第二个答案,我建议扩展完整代码以获得更多可读性:
declare @var1 varchar(100)
declare @var2 varchar(100)
declare @var3 varchar(100)
set @var1 = '(ALL)'
set @var2 = '(x)'
set @var3 = 'data'
declare @var1Inner varchar(100)
declare @var2Inner varchar(100)
declare @var3Inner varchar(100)
declare @var1withNull bit
declare @var2withNull bit
declare @var3withNull bit
SELECT @var1withNull = 0, @var2withNull = 0, @var3withNull = 0
IF (@var1 like '(%)') BEGIN
SELECT @var1withNull = 1, @var1Inner = SUBSTRING(@var1,2,LEN(@var1)-2)
END
IF (@var2 like '(%)') BEGIN
SELECT @var2withNull = 1, @var2Inner = SUBSTRING(@var1,2,LEN(@var1)-2)
END
IF (@var3 like '(%)') BEGIN
SELECT @var3withNull = 1, @var3Inner = SUBSTRING(@var3,2,LEN(@var3)-2)
END
SELECT *
FROM table
WHERE (@var1 = '(ALL)' OR (@var1withNull = 1 AND IsNull(field1,@var1withNull) = @var1withNull) OR field1 = @var1)
AND (@var2 = '(ALL)' OR (@var2withNull = 1 AND IsNull(field2,@var2withNull) = @var2withNull) OR field2 = @var2)
AND (@var3 = '(ALL)' OR (@var3withNull = 1 AND IsNull(field3,@var3withNull) = @var3withNull) OR field3 = @var3)