选择 COST1 与 COST2 不同的简洁方法(处理 null=null)

Succinct way to select where COST1 is different than COST2 (treat null=null)

提问人:User1974 提问时间:7/3/2022 最后编辑:User1974 更新时间:7/4/2022 访问量:55

问:

我有两个数字列:COST1 和 COST2。

值可以是:

  • 负数
  • 正数
with workorder
     (cost1,cost2) as (
select    1,    1 from dual union all
select -100, null from dual union all
select null,    0 from dual union all
select    0,  100 from dual union all
select null, null from dual
)

select
  *
from
  workorder
成本1 成本2
1 1
-100
0
0 100

db<>小提琴


我想选择 COST1 与 COST2 不同的行。

  • 我想把空值看作是相等的。
  • 但我不想将 null 视为零。

结果:

成本1 成本2
-100
0
0 100

它等同于 SQLite 中的语法:is not

with workorder 
(cost1,cost2) as (
values
(   1,    1),
(-100, null),
(null,    0),
(   0,  100),
(null, null)
)

select
  *
from
  workorder
where
  cost1 is not cost2
成本1 成本2
-100
0
0 100

db<>小提琴


如何使用 Oracle SQL 简洁地做到这一点?(简洁胜过性能)

sql oracle null 其中子句 oracle18c

评论


答:

0赞 User1974 7/3/2022 #1

这是一种方法。但它并不像我想要的那么简洁:

with workorder
     (cost1,cost2) as (
select    1,    1 from dual union all
select -100, null from dual union all
select null,    0 from dual union all
select    0,  100 from dual union all
select null, null from dual
)

select
  *
from
  workorder
where
  cost1 <> cost2
  or (cost1 is null and cost2 is not null)
  or (cost1 is not null and cost2 is null)
COST1  COST2
-----  -----
 -100   null
 null      0
    0    100

db<>小提琴

2赞 lemon 7/3/2022 #2

您可以将值转换为字符串,然后使用 NVL 函数将 null 值转换为“null”字符串。因此,检查不等式。

where NVL(CAST(cost1 AS VARCHAR2(10)), 'null') <> NVL(CAST(cost2 AS VARCHAR2(10)), 'null')

另一种选择是将检查空值的两个条件与单个检查组合在一起:两个值的串联应对应于一个或另一个成本值。

where cost1 <> cost2
   OR CONCAT(cost1, cost2) IN (cost1, cost2)

在此处查看演示。

1赞 William Robertson 7/4/2022 #3

用作默认值怎么样?binary_float_nannvl

with workorder (cost1,cost2) as (
    select    1,    1 from dual union all
    select -100, null from dual union all
    select null,    0 from dual union all
    select    0,  100 from dual union all
    select null, null from dual
)
select o.*
from   workorder o
where  nvl(cost1,binary_double_nan) <> nvl(cost2,binary_double_nan)

或者,如果为 ,例如为 定义了精度和小数位数,则合理安全的默认值可能类似于 或 。costnumber(10,2)0.00011/322/7

评论

0赞 User1974 7/4/2022
谢谢。对精度的好要求。我应该在示例数据中包含小数位。