根据行值填充列 BigQuery 标准 SQL
Posted
技术标签:
【中文标题】根据行值填充列 BigQuery 标准 SQL【英文标题】:Populate column based on row values BigQuery Standard SQL 【发布时间】:2020-08-05 06:23:58 【问题描述】:我有一张桌子让我们说:-
Name A B C D
------- --- --- --- ---
alpha 0 1 0 0.6
beta 0.6 0 0 0.1
gama 0 0 0 0.6
现在我想根据 A、B、C、D 值在两列(Result & Class)
上填充值。
条件是,如果任何字段(A、B、C、D)中的值>.5,那么Result
列应该有“F”,否则应该有“P”。 valie >.5 的列也应该在Class
example("A,D")
为了更好地理解这里是我想要的结果:-
Name A B C D Result Class
------- --- --- --- --- -------- -------
alpha 0 1 0 0.6 F B,D
beta 0.6 0 0 0.1 F A
gama 0 0 0 0.4 P NULL
我是 BigQuery 新手,需要帮助。有什么解决方法。
这是我迄今为止所做的事情
SELECT *, CASE WHEN (A > .5 OR B > .5 OR C > .5 OR D >.5)
THEN 'F'
ELSE 'P' END AS Result AND Class....//here i am stuck
FROM table1
实际上,我不知道如何构建这个确切的脚本。我能够实现第一部分,我能够用“F”和“P”填充结果列,但不能让类填充列名....
【问题讨论】:
希望我的问题很清楚。 【参考方案1】:由于您正在分析每一列,我假设您没有大量的列。因此,我创建了一个简单的javascript User Defined Function (UDF) 来检查行的值并在满足条件时返回列的名称。
我已使用提供的示例数据来测试以下查询。
#javaScript UDF
CREATE TEMP FUNCTION class(A FLOAT64, B FLOAT64, C FLOAT64, D FLOAT64)
RETURNS String
LANGUAGE js AS """
var class_array=[];
if(A > 0.5)class_array.push("A");
if(B > 0.5)class_array.push("B");
if(C > 0.5)class_array.push("C");
if(D > 0.5)class_array.push("D");
return class_array;
""";
#sample data
WITH data as (
SELECT "alpha" as Name, 0 as A, 1 as B, 0 as C, 0.6 as D UNION ALL
SELECT "beta", 0.6, 0, 0, 0.1 UNION ALL
SELECT "gama", 0, 0, 0, 0.4
)
Select name, A,B,C,D,
CASE WHEN (A > .5 OR B > .5 OR C > .5 OR D >.5) THEN "F" ELSE "P" END AS Result,
IF(class(A,B,C,D) is null , null, class(A,B,C,D)) as Class from data
还有输出,
Row name A B C D Result Class
1 alpha 0 1 0 0.6 F B,D
2 beta 0.6 0 0 0.1 F A
3 gama 0 0 0 0.4 P
正如 UDF 中所示,每行的值都会被分析,如果满足条件,列的名称会手动添加到字符串数组中。另外,请注意 JS UDF 返回的是字符串,而不是数组。它会自动将之前创建的 Array 转换为 String。
最后,我应该指出,在这种情况下,无法在查询中检索列名。虽然,您可以在其他情况下使用INFORMATION_SCHEMA 检索它。
【讨论】:
我最多有 5500 行,希望这不会超时。【参考方案2】:以下是 BigQuery 标准 SQL
在许多情况下使用 javaScript UDF 会有所帮助,但如果可以使用 SQL 解决问题,如下例所示,则应避免使用
#standardSQL
SELECT *,
( SELECT IF(LOGICAL_OR(val > 0.5), 'F', 'P')
FROM UNNEST([A,B,C,D]) val
) AS Result,
( SELECT STRING_AGG(['A','B','C','D'][OFFSET(pos)])
FROM UNNEST([A,B,C,D]) val WITH OFFSET pos
WHERE val > 0.5
) AS Class
FROM `project.dataset.table`
您可以使用来自我们问题的示例数据进行测试,如下例所示
#standardSQL
WITH `project.dataset.table` AS (
SELECT 'alpha' name, 0 A, 1 B, 0 C, 0.6 D UNION ALL
SELECT 'beta', 0.6, 0, 0, 0.1 UNION ALL
SELECT 'gamma', 0, 0, 0, 0.4
)
SELECT *,
( SELECT IF(LOGICAL_OR(val > 0.5), 'F', 'P')
FROM UNNEST([A,B,C,D]) val
) AS Result,
( SELECT STRING_AGG(['A','B','C','D'][OFFSET(pos)])
FROM UNNEST([A,B,C,D]) val WITH OFFSET pos
WHERE val > 0.5
) AS Class
FROM `project.dataset.table`
输出为
Row name A B C D Result Class
1 alpha 0.0 1 0 0.6 F B,D
2 beta 0.6 0 0 0.1 F A
3 gamma 0.0 0 0 0.4 P null
【讨论】:
以上是关于根据行值填充列 BigQuery 标准 SQL的主要内容,如果未能解决你的问题,请参考以下文章