在 WHERE 子句中正确使用 COALESCE

Using COALESCE correctly in WHERE clause

有人可以解释为什么在以下条件下 coalesce 在 where 子句中不起作用吗?在这种情况下,我们如何在不更改以下合并条件且仅用于 spoiled = Y 的情况下正确使用合并?

Table 水果:

  ITEM_NAME     ITEM_NO     SPOILED
  Apples        A15354        N 
  Bananas       BYHUG1        N
  Grapes        GR0013        Y     
  Oranges       ORULYE        N
  Guavas        GUOIUW        Y

查询:

  select fruit.item_name
  from fruit
  where fruit.item_no = coalesce('A15354','CURR_NOT_IN_TABLE','GR0013','GUOIUW')
  and fruit.spoiled = 'Y'

使用上面的查询不会return任何东西。期望的输出应该是葡萄。

期望的输出:

  Grapes

我们可以在这里使用ROW_NUMBER来select你想要的优先级:

WITH cte AS (
    SELECT f.*, ROW_NUMBER() OVER (ORDER BY DECODE(ITEM_NO, 'A15354', 1,
                                                            'CURR_NOT_IN_TABLE', 2,
                                                            'GR0013', 3,
                                                            'GUOIUW', 4, 5)) rn
    FROM fruit f
    WHERE spoiled = 'Y'
)

SELECT ITEM_NAME
FROM cte
WHERE rn = 1;

这里的想法是为每个被宠坏的项目分配从 1 到 5 的优先级。我们使用 ROW_NUMBER 生成一个序列,该序列始终以 1 开头,即可用的最高优先级。

虽然@Tim Biegeleisen 就如何解决业务问题给出了完美的答案,但它没有回答 OP 的问题。 COALESCE 将 return 参数列表中的第一个 NOT NULL 值。如果像您一样传递 nr 个字符串,则该值将始终是第一个。通常你传递一个列作为参数,它将 return 第一个 NOT NULL 列值

最好的学习方法是反复尝试查询和测试

with fruit (ITEM_NAME,ITEM_NO,SPOILED)
AS
(
SELECT 'Apples',   'A15354','N' FROM DUAL UNION 
SELECT 'Bananas',  'BYHUG1','N' FROM DUAL UNION
SELECT 'Grapes',   'GR0013','Y' FROM DUAL UNION     
SELECT 'Oranges',  'ORULYE','N' FROM DUAL UNION
SELECT 'Guavas',   'GUOIUW','Y' FROM DUAL 
)
select fruit.item_name
  from fruit
  where fruit.item_no = COALESCE('A15354','CURR_NOT_IN_TABLE','GR0013','GUOIUW')

Apples

那是因为 COALESCE 只调用了 return 次 'A15354'。另一种测试它的方法是将该语句包含在您的 SELECT 中,如下所示:

with fruit (ITEM_NAME,ITEM_NO,SPOILED)
AS
(
SELECT 'Apples',   'A15354','N' FROM DUAL UNION 
SELECT 'Bananas',  'BYHUG1','N' FROM DUAL UNION
SELECT 'Grapes',   'GR0013','Y' FROM DUAL UNION     
SELECT 'Oranges',  'ORULYE','N' FROM DUAL UNION
SELECT 'Guavas',   'GUOIUW','Y' FROM DUAL 
)
select 
   fruit.item_name
 , COALESCE('A15354','CURR_NOT_IN_TABLE','GR0013','GUOIUW')
  from fruit

ITEM_NA COALES
------- ------
Apples  A15354
Bananas A15354
Grapes  A15354
Guavas  A15354
Oranges A15354

如您所见,return每一行的值都相同,因为第一个 NOT NULL 值是字符串 A15354。

COALESCE 不是您问题的解决方案,我希望这能解释一下。