Применить отношение к массиву в стандартном SQL - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть две таблицы с большими запросами.Таблица 1 имеет схему {id:String, colors:Array[String]} и выглядит как

| id   | colors                      |
|------|-----------------------------|
| id_1 | ["blue", "green", "orange"] |
| id_2 | ["red" , "blue", "green" ]  |
| ...  | ....                        |

, а таблица 2 связывает цвета с числами со схемой {color:String, number:Int} и выглядит как

| color | number |
|-------|--------|
| "blue"| 0      |
| "red" | 1      |
| ...   | ...    |

Я хочу создать таблицу, котораявыглядит как

| id | numbers |
|----|---------|
|id_1| [0,3,4] |
|id_2| [1,0,3] |
| ...|...      |

, полученный путем сопоставления каждого цвета в таблице 1 с соответствующим номером.Единственное решение, которое я могу придумать, это

SELECT id, ARRAY_AGG(number) AS numbers
FROM (table_1 CROSS JOIN UNNEST(table_1.colors) as color) JOIN table_2 USING(color) 
GROUP BY email

, но это занимает очень много времени (возможно, потому что перекрестное соединение)

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT id,
  ARRAY(
    SELECT number FROM table_1.colors color 
    JOIN `project.dataset.table_2` USING (color) 
  ) AS numbers
FROM `project.dataset.table_1` table_1   

Вы можете протестировать, поиграть с выше, используя примеры данных из вашего вопроса, как в примере ниже

#standardSQL
WITH `project.dataset.table_1` AS (
  SELECT 'id_1' id, ["blue", "green", "orange"] colors UNION ALL
  SELECT 'id_2', ["red" , "blue", "green" ] 
), `project.dataset.table_2` AS (
  SELECT 'blue' color, 0 number UNION ALL
  SELECT 'red', 1 UNION ALL
  SELECT 'green', 3 UNION ALL
  SELECT 'orange', 4
)
SELECT id,
  ARRAY(
    SELECT number FROM table_1.colors color 
    JOIN `project.dataset.table_2` USING (color) 
  ) AS numbers
FROM `project.dataset.table_1` table_1   

с результатом

enter image description here

0 голосов
/ 09 февраля 2019

Что-то простое, как это:

select id, array_agg(number) as numbers from (
  select id, c, t2.number from table_1 t1, unnest(t1.colors) c
  join table_2 t2 on c = t2.color
)
group by 1
0 голосов
/ 09 февраля 2019

Вы также можете сформулировать это следующим образом:

SELECT email,
       (SELECT ARRAY_AGG(number) AS numbers
        FROM UNNEST(table_1.colors) color JOIN 
             table_2
        USING (color) 
       ) as colors
FROM table_1;

Я не уверен, будет ли «локальное» агрегирование в каждой строке работать лучше, чем «общее» агрегирование в BigQuery.Но это стоит попробовать.

...