【问题标题】:How to use `GREATEST()` in Snowflake with null values?如何在具有空值的 Snowflake 中使用 `GREATEST()`?
【发布时间】:2022-11-22 13:20:40
【问题描述】:

我正在尝试在 Snowflake 中使用 GREATEST(),但每当我有空值时,我都会得到 null 而不是所需的结果:

select greatest(1,2,null);

-- null

这种行为让很多人感到困惑,它始于 Oracle 中 GREATEST() 的行为,Snowflake 匹配到:

它也在 Snowflake 论坛中进行了讨论:

样本数据:

create or replace table some_nulls
as (
    select $1 a, $2 b, $3 c
    from values(1.1, 2.3, null::float), (null, 2, 3.5), (1, null, 3), (null, null, null)
);

select greatest(a, b)
from some_nulls;

在这里询问以获得最佳的可用解决方案。

【问题讨论】:

    标签: sql snowflake-cloud-data-platform


    【解决方案1】:

    一个解决方案可能是创建一个 UDF,它选择 greatest() 或第一个非空值:

    create or replace function greatest2(x1 float, x2 float)
    returns float
    as $$
        coalesce(greatest(x1, x2), x1, x2)
    $$;
    
    select greatest2(a, b)
    from some_nulls;
    

    但是,如果您需要比较多个值,事情就会变得更加复杂。例如,如果要比较 3 列,则必须创建一个包含 3 个参数的自定义 UDF,并检查每个参数是否为空:

    create or replace function greatest3(x1 float, x2 float, x3 float)
    returns float
    as $$
        select iff(x='-inf', null, x)
        from (
            select greatest(nvl(x1, '-inf'), nvl(x2, '-inf'), nvl(x3, '-inf')) x
        )
    $$;
    
    select greatest3(a, b, c)
    from some_nulls;
    

    【讨论】:

    • 此 UDF 仅适用于 2 个值。 3个或更多呢?
    • 我为 2 添加了一个,为 3 添加了一个。对于更多,我希望看到更多答案(或遵循与 3 相同的模式)
    【解决方案2】:

    在这里记录一种不起作用的方法(以节省其他人的时间或修复的机会):SQL UDF 中的数组。

    create or replace function greatest_a(arr array)
    returns float
    immutable
    as $$
        select max(value::float)
        from table(flatten(arr))
    $$;
    
    select greatest_a([null,2,3.3])
    from some_nulls;
    

    这一直有效,直到您尝试使用表中的值创建数组。

    select greatest_a([a, b, c])
    from some_nulls;
    
    -- Unsupported subquery type cannot be evaluated
    

    使用 JS UDF 的类似方法可以工作,但它会比纯 SQL UDF 慢。

    【讨论】:

      猜你喜欢
      • 2017-12-20
      • 1970-01-01
      • 2017-12-11
      • 2021-03-25
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      相关资源
      最近更新 更多