Заполнение столбца на основе значений строки BigQuery Standard SQL - PullRequest
1 голос
/ 05 августа 2020

У меня есть таблица, которая позволяет сказать: -

  Name   A    B    C    D    
------- ---  ---  ---  --- 
 alpha   0    1    0   0.6     
 beta   0.6   0    0   0.1
 gama    0    0    0   0.6

Теперь я хочу заполнить значения в двух столбцах (Result & Class) на основе значений A, B, C, D.

Условие состоит в том, что если значение в любом из полей (A, B, C, D)> .5, то столбец Result должен иметь «F», иначе он должен иметь «P». Также столбец, значение которого ie равно> .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», но не смог заставить класс заполнять имена столбцов ....

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Ниже для BigQuery Standard 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       
1 голос
/ 05 августа 2020

Поскольку вы анализируете каждый столбец, я предполагаю, что у вас нет большого количества столбцов. Поэтому я создал простую JavaScript определяемую пользователем функцию (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 возвращает строку, а не массив. Он автоматически преобразует ранее созданный массив в String.

Наконец, я должен указать, что в этом контексте невозможно получить имя столбца в запросе. Хотя вы можете получить его в другом сценарии ios, используя INFORMATION_SCHEMA .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...