Gra*_*ace 2 sql postgresql google-bigquery google-cloud-platform
我正在尝试将postgres脚本迁移到bigquery,最终目的是两个脚本都返回完全相同的表(模式和值)。
尝试在我的bigquery select中复制postgres中的minimum()行为时遇到问题。
在postgres中,如果minimum()调用的任何参数为null,则将跳过它们并返回最小非null值。但是,在bigquery中,如果minimum()调用的任何参数为null,则该函数自动返回null。
我正在寻找一种优雅的解决方案来复制bigquery中的postgres minimum()行为。我当前的笨拙解决方案如下:
Postgres(返回-1
):
SELECT LEAST(1, 0, -1, null)
Run Code Online (Sandbox Code Playgroud)
BigQuery(返回null
):
SELECT LEAST(1, 0, -1, null)
Run Code Online (Sandbox Code Playgroud)
Postgres(返回-1
):
SELECT LEAST(COALESCE(1, 0, -1, null),
COALESCE(0, 1, -1, null),
COALESCE(-1, 0, 1, null),
COALESCE(null, 0, -1, 1))
Run Code Online (Sandbox Code Playgroud)
BigQuery(返回-1
):
SELECT LEAST(COALESCE(1, 0, -1, null),
COALESCE(0, 1, -1, null),
COALESCE(-1, 0, 1, null),
COALESCE(null, 0, -1, 1))
Run Code Online (Sandbox Code Playgroud)
这是可行的,但不是理想的解决方案。
在我需要迁移的原始postgres脚本中,存在嵌套的逻辑,例如least(w, x, least(y, z))
,随着值/复杂度的增长,修复变得指数级地不可读。当您尝试将其作为一个巨大的CASE
块时,也会遇到相同的问题。
如果有人能找到我所缺少的明显修补程序,或者以更优雅的方式来反映bigquery中的postgres行为,我们将不胜感激!
小智 8
没有函数:
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
Run Code Online (Sandbox Code Playgroud)
Oracle 和 Vertica 的行为与 BigQuery 相同,遵循 SQL 函数的一般规则 - 如果参数之一为 NULL - 结果为 NULL。PostgreSQL对该规则有一个例外,在文档中明确指出:
仅当所有表达式的计算结果均为 NULL 时,结果才会为 NULL。
请注意,GREATEST 和 LEAST 不在 SQL 标准中,而是常见的扩展。其他一些数据库使它们在任何参数为 NULL 时返回 NULL,而不是仅当所有参数均为 NULL 时才返回 NULL。
我会在 BigQuery 问题跟踪器中打开功能请求,将IGNORE NULLS
参数添加到 LEAST 和 GREATEST 以获得 PostgreSQL 兼容的行为。尽管通常IGNORE NULLS
仅适用于聚合函数,但 LEAST 和 GREATEST 与聚合函数有点相似。
BigQuery Standard SQL有一个简单的解决方法
您只需创建自己的函数(例如myLeast)
,即可在“独立”以及嵌套方案中使用
#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
Run Code Online (Sandbox Code Playgroud)
输出是
least_standard least_less_than_ideal least_workaround least_with_nested
null -1 -1 -2
Run Code Online (Sandbox Code Playgroud)
前两个来自您的问题-第三个是“独立”和嵌套的解决方法
希望您可以将这种方法应用于您的特定情况
归档时间: |
|
查看次数: |
283 次 |
最近记录: |