【问题标题】:Is it possible to insert an IF clause inside of a WHERE clause in a SELECT?是否可以在 SELECT 的 WHERE 子句中插入 IF 子句?
【发布时间】:2017-01-20 23:26:54
【问题描述】:

对不起,如果这是一个愚蠢的问题,我是 PL/SQL 的新手。 我有一个从表中检索数据的 PL/SQL 存储过程。 有 2 个可选参数可以为空。如果它们不为 null,它们应该是 WHERE 子句的一部分。

这是选择:

SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION
FROM           MAS_PART              PN
LEFT JOIN      CF_DESCRIPTION        DES  
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID              
WHERE PN.PART_CODE = 'M'
AND PN.PART_TYPE_ID = IN_PART_TYPE_ID
AND PN.PART_GROUP_ID = IN_PART_GROUP_ID
ORDER BY PN.PART_NUMBER;

这两个变量是 IN_PART_TYPE_ID 和 IN_PART_GROUP_ID。有没有办法仅在它们不为空时评估关于这两个变量的 WHERE 子句?还是唯一的方法是使用 IF 子句重复 SELECT 3 次并更改 WHERE 子句?

【问题讨论】:

  • where ( col = param or param is null) and ...

标签: sql database oracle


【解决方案1】:

OR 操作员将提供帮助:

SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION
FROM           MAS_PART              PN
LEFT JOIN      CF_DESCRIPTION        DES  
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID              
WHERE PN.PART_CODE = 'M'
AND (PN.PART_TYPE_ID = IN_PART_TYPE_ID or IN_PART_TYPE_ID is null)
AND (PN.PART_GROUP_ID = IN_PART_GROUP_ID or IN_PART_GROUP_ID is null)
ORDER BY PN.PART_NUMBER;

另一种选择是使用 NVL:

SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION
FROM           MAS_PART              PN
LEFT JOIN      CF_DESCRIPTION        DES  
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID              
WHERE PN.PART_CODE = 'M'
AND PN.PART_TYPE_ID = NVL(IN_PART_TYPE_ID, PN.PART_TYPE_ID)
AND PN.PART_GROUP_ID = NVL(IN_PART_GROUP_ID, PN.PART_GROUP_ID)
ORDER BY PN.PART_NUMBER;

但只有当 PN.PART_TYPE_ID 和 PN.PART_GROUP_ID 不为空时才会起作用

【讨论】:

  • 您可以将其扩展为:AND nvl(PN.PART_TYPE_ID,'X#z') = NVL(IN_PART_TYPE_ID, nvl(PN.PART_TYPE_ID,'X#z')) 以覆盖空值。其中X#z 是某个列中不存在的字符串。
  • 但如果您在列上有索引,则将考虑为(column=some_expression),而不是(some_function(column)=some_expression)
  • 如果表中的值为NULL,则使用NVL 将不会给出与第一个查询相同的答案。尝试SELECT CASE WHEN NULL = NVL( NULL, NULL ) THEN 1 ELSE 0 END FROM DUAL 并将其与SELECT CASE WHEN ( NULL = NULL OR NULL IS NULL ) THEN 1 ELSE 0 END FROM DUAL 进行比较。
  • 为什么会有人想在这里使用nvl吗?条件中OR 有什么问题?
  • @mathguy - 刚刚做了一个快速测试。作为参数传入的 Null 有效,并且在表列中包含 null 有效。涉及 NVL 的解决方案是无关紧要的,并且不适用于所有可能的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 2020-01-08
  • 1970-01-01
  • 2021-12-22
相关资源
最近更新 更多