用于返回结果集的 where 子句中的 case 语句包含空值

Posted

技术标签:

【中文标题】用于返回结果集的 where 子句中的 case 语句包含空值【英文标题】:case statement in where clause to return results set include nulls 【发布时间】:2019-05-23 22:36:43 【问题描述】:

我正在做一个碧玉报告,该报告通过多个参数进行过滤,这些参数是可选的,使用 where 子句中的 case 语句。如果未输入参数,我希望结果集满足其他参数还包括空值。

我在 where 子句中做了一个 case 语句。排除我的最后一个条件,我得到了我想要的结果。当参数为空时,我希望在结果中满足其他条件,包括由 where 子句中的其他条件满足的空记录

SELECT
cert.ice_certificate_date_issued AS "START_DATE",
cert.ice_current_license_expiry AS "END_DATE",
--licence_type,
ib.name AS "SHOP",
cert.ice_license_fee AS "SUPERMARKETPRICE",
dist.name AS "DISTRICT",
,iba.ice_price)
,0) AS "ACTIVITY_PRICE",
(select nvl(sum(taxamt),0) from c_ordertax where c_order_id = cert.c_order_id) AS "TAXAMT"
FROM icp_certificate cert
LEFT JOIN c_order ord ON cert.c_order_id = ord.c_order_id
LEFT JOIN icp_business ib ON cert.ice_foreign_trx_entity_id = 
ib.icp_business_id
LEFT JOIN c_bpartner cbp ON cert.c_bpartner_id = cbp.c_bpartner_id
LEFT JOIN c_bpartner_location cbpl ON cert.c_bpartner_id = 
cbpl.c_bpartner_id
LEFT JOIN icp_district dist ON cbpl.ice_district_id = 
dist.ice_district_id
LEFT JOIN c_location loc on ib.c_location_id = loc.c_location_id
LEFT JOIN icp_business_activity_link ibal ON ib.icp_business_id = 
ibal.icp_business_id
LEFT JOIN icp_business_activity iba ON ibal.icp_business_activity_id = 
iba.icp_business_activity_id
WHERE
cert.ad_client_id = 1000555 AND
cert.ad_org_id = 2010520 AND
cert.icp_certificate_status = '01' AND
cert.isactive = 'Y' AND
cert.ice_certificate_type = '0051' AND
cert.ice_currentcertificate = 'Y' AND
cert.icp_certificate_date_issued BETWEEN '01-JAN-19' AND '23-MAY-19' AND
ib.ICp_District_ID = CASE WHEN 0>0 THEN 46445665 else ib.ICp_District_ID 
END

--我希望 else 部分包含 ib.ICp_District_ID 为空的记录

返回其他条件内的所有结果,包括区 id 为空的记录

【问题讨论】:

WHEN 0>0 的意义何在?那总是错误的。 嗨,当 param>0 进入 THEN 部分但我现在只输入 0>0 来测试 else 部分。 【参考方案1】:

在我看来你可以使用

.
.
.
(ib.ICp_District_ID = CASE
                        WHEN 0>0 THEN 46445665
                        else ib.ICp_District_ID 
                      END
 OR
 ib.ICp_District_ID IS NULL)

可以简化为

NVL(ib.ICp_District_ID, -99) = NVL(ib.ICp_District_ID, -99)

因为 CASE 表达式将始终返回 ib.ICp_District_ID。它可以通过完全省略检查ib.ICp_District_ID 的条件来进一步简化,因为它总是会得到满足。 (当然,假设您打算将条件 WHEN 0 > 0 保留在 CASE 表达式中,该条件始终为 FALSE,因此它始终会落入 ELSE)。

祝你好运。

【讨论】:

嗨 Bob Jarvis 哇,非常感谢第一个选项有效。也想了解简化的。 WHEN 0>0 始终为 false,因此 CASE 表达式始终返回 ib.ICp_District_ID。因此,第一种情况实际上是(ib.ICp_District_ID = ibICp_District_ID OR ib.ICp_District_ID IS NULL),它始终为 TRUE。第二种情况基本上是说“将 ib.ICp_District_ID 与自身进行比较,除非 ib.ICp_District_ID 为 NULL,在这种情况下,将 -99 替换为 NULL 并将 -99 与 -99 进行比较(始终相等)”。所以第二种情况总是返回 TRUE。因此,由于 case 1 或 case 2 将始终返回 TRUE,因此我们根本不需要进行此检查,因为它不会过滤掉任何结果。

以上是关于用于返回结果集的 where 子句中的 case 语句包含空值的主要内容,如果未能解决你的问题,请参考以下文章

Oracle where 子句中的 case 表达式

Where 子句 TSQL 中的 case 表达式

MySQL CASE WHEN where 子句导致失败

WHERE 子句中的 CASE

如何使用 case 语句来确定存储过程中的 from 和 where 子句?

where 子句 oracle 中的 case 语句