2017-02-13 5 views
0

Я хочу автоматизировать создание «переменных каталога» из набора URIS до тех пор, пока не будет достигнуто максимальное количество каталогов.Автоматизация создания последовательности переменных в BigQuery

Например, если бы я имел 4 каталоги из URI: "/A/B/C/17628.html", я хотел бы создать следующие переменные:

  1. path_1 = "A"
  2. path_2 = "B"
  3. path_3 = "C"
  4. path_4 = "17628.html"

Но если бы у меня было: "/A/D/E/F/178.html":

  1. path_1 = "A"
  2. path_2 = "D"
  3. path_3 = "E"
  4. path_4 = "F"
  5. path_5 = "178.html"

Это вероятно, иметь URI с большим количеством каталогов (до 20). Чтобы избежать создания всех этих переменных вручную, я хочу определить их , используя цикл for (или другой вариант). Можно использовать этот цикл в BigQuery?

+0

Что такое ожидаемый вывод запроса, учитывая URI '' /A/B/C/17628.html? '? Невозможно создать столбцы динамически - если вы не делаете этого в своем собственном коде, - но есть ли намерение получить пять строк, в которых каждый содержит часть URI? –

+0

У моего набора данных есть в первом столбце URI.Вывод запроса должен иметь в столбцах разные подкаталоги (путь1, путь2 ... путь). Если URI имеет 1 подкаталог, path2 ... pathn будет заполнен как null. –

+0

Я хочу что-то вроде этого (код неправильный): SELECT FOR (i от 1 до MAX (LENGTH (URI) -LENGTH (REPLACE (URI, '/', ''))) AS CONCAT (путь, i) FROM [my_table_URI] –

ответ

0

Необходимо явно указать столбцы в списке выбора; сами колонки не могут быть динамическими. Если все в порядке с получением результатов обратно в массив, вы могли бы сделать что-то вроде этого:

#standardSQL 
WITH T AS (
    SELECT '/A/B/C/17628.html' AS path UNION ALL 
    SELECT '/A/D/E/F/178.html' AS path 
) 
SELECT 
    ARRAY(SELECT IFNULL(subpaths[SAFE_OFFSET(x)], '') 
     FROM UNNEST(GENERATE_ARRAY(0, 19)) AS x) AS paths 
FROM (
    SELECT SPLIT(path, '/') AS subpaths 
    FROM T 
); 

Если вы хотите явные path_1, path_2 и т.д. столбцы можно сделать:

#standardSQL 
WITH T AS (
    SELECT '/A/B/C/17628.html' AS path UNION ALL 
    SELECT '/A/D/E/F/178.html' AS path 
) 
SELECT 
    subpaths[SAFE_OFFSET(1)] AS path_1, 
    subpaths[SAFE_OFFSET(2)] AS path_2, 
    subpaths[SAFE_OFFSET(3)] AS path_3, 
    subpaths[SAFE_OFFSET(4)] AS path_4, 
    subpaths[SAFE_OFFSET(5)] AS path_5, 
    subpaths[SAFE_OFFSET(6)] AS path_6, 
    subpaths[SAFE_OFFSET(7)] AS path_7, 
    subpaths[SAFE_OFFSET(8)] AS path_8, 
    subpaths[SAFE_OFFSET(9)] AS path_9, 
    subpaths[SAFE_OFFSET(10)] AS path_10, 
    subpaths[SAFE_OFFSET(11)] AS path_11, 
    subpaths[SAFE_OFFSET(12)] AS path_12, 
    subpaths[SAFE_OFFSET(13)] AS path_13, 
    subpaths[SAFE_OFFSET(14)] AS path_14, 
    subpaths[SAFE_OFFSET(15)] AS path_15, 
    subpaths[SAFE_OFFSET(16)] AS path_16, 
    subpaths[SAFE_OFFSET(17)] AS path_17, 
    subpaths[SAFE_OFFSET(18)] AS path_18, 
    subpaths[SAFE_OFFSET(19)] AS path_19, 
    subpaths[SAFE_OFFSET(20)] AS path_20 
FROM (
    SELECT SPLIT(path, '/') AS subpaths 
    FROM T 
); 

С Я не хотел, чтобы написать этот список вручную, я побежал простой однострочник в моем терминале:

for i in `seq 1 20`; do echo "subpaths[SAFE_OFFSET($i)] AS path_$i,"; done 
1

Рассмотрим ниже версии

#standardSQL 
WITH yourTable AS (
    SELECT '/A/B/C/17628.html' AS uri UNION ALL 
    SELECT '/A/D/E/F/178.html' AS uri 
) 
SELECT uri, CONCAT('path_', CAST(1 + OFFSET AS STRING)) AS pos, path 
FROM yourTable, UNNEST(SPLIT(REGEXP_EXTRACT(uri, r'/(.*)/'), '/')) path WITH OFFSET 
ORDER BY uri, OFFSET 

результат:

uri     pos  path  
/A/B/C/17628.html path_1  A  
/A/B/C/17628.html path_2  B  
/A/B/C/17628.html path_3  C  
/A/D/E/F/178.html path_1  A  
/A/D/E/F/178.html path_2  D  
/A/D/E/F/178.html path_3  E  
/A/D/E/F/178.html path_4  F  

В большинстве практических случаев, имея такую ​​сплюснутый схему по сравнению с повернута - гораздо легче иметь дело (запрос) с

В случае, если вы все еще хотите выровнять выше результата - см. один из моих многочисленных ответов на эту тему - Transpose rows into columns in BigQuery (Pivot implementation)

Смежные вопросы