我有一个SQLExpress表,其中包含一个用于存储TRUE / FALSE状态的位字段。
类似的东西:
+----+---------+
| ID | IsAlive |
+----+---------+
| 1 | 1 |
| 2 | 0 |
| 3 | NULL |
| 4 | 1 |
+----+---------+
使用该表作为示例,我想创建一个将执行以下任一操作的存储过程:
IsAlive=1
的记录。IsAlive=0 or NULL
的记录。我正在考虑如何创建我的查询而不必编写IF / ELSE条件 - 在我看来,有一种更好/更清洁的方式,而不是做这样的事情:
-- The ternary logic...
-- 0 or NULL retrieves records where IsAlive = 0 or NULL
-- 1 retrieves records where IsAlive = 1
-- Otherwise return all records
-- sproc .....
@IsAlive tinyint = 2 -- Return all records by default
AS
BEGIN
IF(@SentToNTService = 0 OR @SentToNTService = 1)
BEGIN
SELECT *
FROM MyTable
WHERE IsAlive = @IsAlive;
END
ELSE -- Lame redundancy
BEGIN
SELECT *
FROM MyTable
END
END
是否有另一种创建相同结果的方法,而不必像上面那样创建两个不同的查询?
答案 0 :(得分:5)
有关如何执行此操作的2条建议:
假设你的变量@isalive也被声明为'bit'(应该是)
SELECT * FROM @t
WHERE @isalive is null or @isalive = coalesce(isalive, 0)
如果你想使用'比较'解决方案,不需要@isalive为'bit'(它可以用于bit和tinyint)
SELECT * FROM @t
WHERE coalesce((1-coalesce(isalive, 0)) ^ @isalive, 1) > 0
第二种解决方案适用于像我这样的书呆子。一些铁杆人可能会发现它很有趣(或者至少是有趣的)因为我认为它提供了最好的性能(如果我错了,请有人纠正我)。这是一个强大的解决方案,但很难阅读。
答案 1 :(得分:3)
这将做你想要的:
SELECT *
FROM MyTable
WHERE COALESCE(IsAlive, 0) = COALESCE(@IsAlive, COALESCE(IsAlive, 0))
基于@IsAlive的值:
COALESCE是一个函数,它返回它的第一个参数,除非它是NULL,在这种情况下它返回它的第二个参数。
因此,如果IsAlive为NULL或0,则LHS返回0;如果IsAlive为1,则LHS返回1。 当存储过程参数@IsAlive为NULL时,RHS返回相同的值,否则返回@IsAlive参数。
修改强> 这假设@IsAlive是BIT。对于tinyint,您可以添加一个case语句:
SELECT *
FROM MyTable
WHERE COALESCE(IsAlive, 0) = CASE @IsAlive
WHEN 0 THEN 0
WHEN 1 THEN 1
ELSE COALESCE(IsAlive, 0)
END
答案 2 :(得分:1)
试试这个:
SELECT * FROM MyTable WHERE ISNULL (IsAlive, 0) = ISNULL (@IsAlive, 0)
UNION
SELECT * FROM MyTable WHERE ISNULL (@IsAlive, 0) > 1
答案 3 :(得分:1)
这不完全正确,但与您可以做的非常接近:
SELECT *
FROM MyTable
WHERE CASE @IsAlive
WHEN 0 THEN IsAlive = @IsAlive
WHEN 1 THEN IsAlive = @IsAlive
ELSE 1=1 --dummy true value, when null or anything else
END
答案 4 :(得分:1)
这样的事情也应该有效。
SELECT *
FROM MyTable
WHERE (@IsAlive = 0 and IsAlive=0)
OR (@IsAlive =1 and IsAlive =1)
OR (@IsAlive is null)