mysql - WHERE 之后的 CASE 语句那么几个值之一可以为 NULL?
问题描述
我有这样的选择:
SELECT
*
FROM
Table Tb
WHERE
Tb.LastModificationDate BETWEEN @StartDate And @EndDate
AND Tb.var1 = @var1
AND Tb.var2 = @var2
@var1 和 @var2 可能为空(或只有其中一个),所以现在我为每种情况选择了 3 个(真正的选择更复杂,所以我提供了简化的示例)我正在尝试合并它们使用 CASE 进行一次选择,但到目前为止还没有运气 - 因为如果其中一个变量不为空,则无法理解如何包含 AND 子句。我相信它应该是这样的:
SELECT
*
FROM
Table Tb
WHERE
Tb.LastModificationDate BETWEEN @StartDate And @EndDate
(CASE WHEN @var1 IS NOT NULL THEN (AND Tb.var1 = @var1)
WHEN @var2 IS NOT NULL THEN (AND Tb.var2 = @var2)
END);
有什么建议吗?
解决方案
要使用该CASE
语句,您需要AND
从该部分中删除该子句THEN
并将其移至外部CASE
以便评估结果。这是因为CASE
不能将条件附加到WHERE
子句 ( THEN AND
)。
SELECT *
FROM Table Tb
WHERE Tb.LastModificationDate BETWEEN @StartDate And @EndDate
AND (CASE
WHEN @var1 IS NOT NULL THEN Tb.var1 = @var1
WHEN @var2 IS NOT NULL THEN Tb.var2 = @var2
END);
但是,上述方法将仅限于CASE @var* IS NOT NULL
评估为 true 的第一个 " "。因此,如果同时提供@var1
and @var2
,则 CASE 只会返回Tb.var1 = @var1
,不会比较Tb.var2 = @var2
。要在两者和都是
时检索结果,需要将其添加到语句中。@var1
@var2
NULL
ELSE true
CASE
(CASE
WHEN @var1 IS NOT NULL THEN Tb.var1 = @var1
WHEN @var2 IS NOT NULL THEN Tb.var2 = @var2
ELSE true
END);
绕过第一种情况限制的另一种方法是通过使用将标准直接应用于WHERE
子句AND (IS NULL OR ...)
。
这将允许标准在以下 4 个条件下匹配:
- 不检查是否
@var1
两者@var2
都是NULL
@var1
如果提供 (Tb.var1 = @var1
)@var2
如果提供 (Tb.var2 = @var2
)@var1
@var2
如果两者都提供(Tb.var1 = @var1 AND Tb.var2 = @var2
)
SELECT *
FROM Table Tb
WHERE Tb.LastModificationDate BETWEEN @StartDate And @EndDate
AND (@var1 IS NULL OR Tb.var1 = @var1)
AND (@var2 IS NULL OR Tb.var2 = @var2);
工作示例:DB-Fiddle
推荐阅读
- couchdb - 如何从超级账本结构中查看或检索数据
- sql - Pivot sql 输出 - Google sql 面试题
- laravel - 访问 Laravel 中的许多页面后重定向到预期的 url
- java - 使用 spring Web Client 命中 https 休息服务
- python - 如何让乌龟遵循我的 IF 语句
- python-3.x - 我可以在使用 urllib3 和 socks 代理时设置一个超时值吗
- delaunay - Delaunay三角剖分顶点插入
- matlab - 如何有效地应用二进制函数来选择 2 个表的列,并且仅根据某些条件选择行?
- r - 用组名及其方程标记 ggplot,可能用 ggpmisc?
- bootstrap-4 - 为什么我的引导和媒体查询没有响应