纠正将最低()行为迁移到bigquery

问题描述 投票:0回答:5
postgres(返回

-1

):

SELECT LEAST(1, 0, -1, null)

bigquery(返回

null

):

SELECT LEAST(1, 0, -1, null)

postgres(返回
-1
):

SELECT LEAST(COALESCE(1, 0, -1, null),
             COALESCE(0, 1, -1, null),
             COALESCE(-1, 0, 1, null),
             COALESCE(null, 0, -1, 1))

bigquery(返回
-1
):

SELECT LEAST(COALESCE(1, 0, -1, null),
             COALESCE(0, 1, -1, null),
             COALESCE(-1, 0, 1, null),
             COALESCE(null, 0, -1, 1))

这起作用,但不是理想的解决方案。
在我需要迁移的原始Postgres脚本中,有嵌套的逻辑,例如

least(w, x, least(y, z))

,因此随着值/复杂度的增长,修复程序变得更加不可读取。当您尝试将其作为一个大型块时,同样的问题也适用。 

如果有人有一个明显的修复,或者我缺少的方法是反映BigQuery的Postgres行为的更优雅的方法,那将是非常感谢的!
    

对于BigQuery Standard SQL

来说,这是一个简单的解决方法

您只需创建自己的功能(例如myleast)
它适用于“独立”以及在嵌套场景中
CASE

输出为

#standardSQL CREATE TEMP FUNCTION myLeast(x ARRAY<INT64>) AS ((SELECT MIN(y) FROM UNNEST(x) AS y)); SELECT LEAST(1, 0, -1, NULL) AS least_standard, LEAST(COALESCE(1, 0, -1, NULL), COALESCE(0, 1, -1, NULL), COALESCE(-1, 0, 1, NULL), COALESCE(NULL, 0, -1, 1)) AS least_less_than_ideal, myLeast([1, 0, -1, NULL]) AS least_workaround, myLeast([1, 0, -1, NULL, myLeast([2, 0, -2, NULL])]) AS least_with_nested
sql postgresql google-bigquery google-cloud-platform
5个回答
8
投票

希望您可以将此方法应用于您的特定案例


没有函数:
least_standard  least_less_than_ideal   least_workaround    least_with_nested    
null            -1                      -1                  -2   

甲骨文和Vertica的行为与BigQuery相同,遵循SQL函数的一般规则 - 如果其中一个参数为null,则结果为null。 PostgreSQL对该规则有例外,在文档中明确说明:

仅当所有表达式评估为null时,结果才会为null。

注意,最大和最少的不在SQL标准中,但是一个 通用扩展。其他一些数据库使它们返回null,如果有 论点为null,而不是仅在所有情况下都是无效的。

8
投票
I将在BigQuery Diseage Tracker中打开功能请求,以将

select (select min(col) from unnest([a,b,c,d,e]) col) least, (select max(col) from unnest([a,b,c,d,e]) col) greatest, * from ( select 1 a, 2 b, 3 c, null d, 5 e union all select null a, null b, null c, null d, null e ) tbl

参数添加到最少和最大的参数,以获得PostgreSQL兼容行为。即使通常仅适用于汇总函数,但最少和最大的功能与汇总函数相似。


6
投票

IGNORE NULLS

如何? :)“ Postgres库”:)

IGNORE NULLS

当然,它可以通过动态的“身体”来改善,但我希望没有人会使用它。 这太可悲了,无法在世界上生活,而没有

WITH tbl AS(
    SELECT 1 AS a, 2  AS b
    UNION ALL SELECT NULL, 2
    UNION ALL SELECT 1, NULL
    UNION ALL SELECT NULL, NULL
)
SELECT 
    tbl.*
    , COALESCE( LEAST(a, b), a , b) 
FROM tbl
    DECLARE input STRING DEFAULT (
    WITH t AS 
    (
        SELECT 1 a, 0 b, -1 c, null d
        UNION ALL 
        SELECT  0, 1, -1, null
        UNION ALL 
        SELECT -1, 0, 1, null
        UNION ALL 
        SELECT null, 0, -1, 1
    )
    SELECT  '['||STRING_AGG("'"||TO_JSON_STRING(t)||"'")||']' FROM t    
)
;
EXECUTE IMMEDIATE '''  
    SELECT * FROM EXTERNAL_QUERY("project.location.connection", 
    \'\'\'
    SELECT 
    GREATEST (
        (t::json->>'a')::INT,
        (t::json->>'b')::INT,
        (t::json->>'c')::INT,
        (t::json->>'d')::INT
    ) 
    FROM
    UNNEST (ARRAY '''||input||")  AS t ''')"

GREATEST

1
投票
IGNORE NULLS

...也无法将字符串变量引导到

GREATEST
LEAST

0
投票
😔

😔

😔
😔
😔

😔

社区问题

任何人都知道这种“方法”的限制?

允许在

EXTERNAL_QUERY
中执行长字符串。
争论
EXECUTE IMMEDIATE

    

如果您的列是“ A”,“ B”和“ C”,其中任何一个都可能在任何行中具有零值,则可以使用无限的值和合并来获得最小值,同时忽略nulls,然后用null替换无限值:
  1. EXTERNAL_QUERY
  2. 
    
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.