Есть ли способ в большом запросе для выполнения динамических запросов что-то вроде «EXEC» в SQL Server? - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть таблица с более чем 200 именами столбцов, которые создаются с временным именем, например - custColum1 -custColum200.

У меня есть таблица сопоставления, которая содержит список custColum1-custColumn200, с именем которого оно должно быть сопоставлено. Например

Table1(custColum1,custColum2) 
Mappingtable(tempColumnName,RealColumnName) 
data in mapping table be like 
(custColum1,Role_number)
(custColum2,Person_name)

Мне нужно изменить таблицу 1 на Table1 (Role_number, Person_name). Примечание: я не могу создать table1 с этим именем, так как я не знаю, какой столбец будет отображен.

Подумал, можем ли мы сделать что-то вроде создания динамического запроса и выполнить, как показано ниже

SET @Sql = 'ALTER TABLE TABLE_NAME RENAME Column columnName'
           print  (@Sql)
           EXEC (@Sql)

Есть ли способ сделать это в BigQuery? Любые идеи будут великолепны

1 Ответ

2 голосов
/ 05 апреля 2019

Давайте предположим упрощенный пример, как показано ниже

Table1
enter image description here

Mappingtable
enter image description here

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

#standardSQL
CREATE OR REPLACE TABLE `project.dataset.Table1` AS 
SELECT NULL AS Role_number, NULL AS Person_name  -- this line to be generated
  FROM (SELECT 1) WHERE FALSE UNION ALL
SELECT * FROM `project.dataset.Table1`  

Теперь нам нужно «разобраться», как сгенерировать нижнюю строку из вышеприведенного запроса

'SELECT NULL AS Role_number, NULL AS Person_name' 

Это можно сделать, выполнив запрос ниже

#standardSQL
SELECT CONCAT('SELECT', STRING_AGG(CONCAT(' NULL AS ', RealColumnName) ORDER BY pos)) select_statement
FROM (
  SELECT TO_JSON_STRING(t) AS cols FROM `project.dataset.Table1` t LIMIT 1
), UNNEST(REGEXP_EXTRACT_ALL(cols, r'"(.*?)":')) col WITH OFFSET AS pos
LEFT JOIN `project.dataset.Mappingtable` ON tempColumnName = col  

Это даст именно ту строку, которая нам нужна

'SELECT NULL AS Role_number, NULL AS Person_name'   

Итак, теперь вопрос в том, как добавить выше динамически построенный фрагмент в интересующий нас запрос!
К сожалению, это не выполнимо как один запрос исключительно внутри BigQuery, но супер простая задача для выполнения в ЛЮБОМ клиенте или инструменте по вашему выбору

Я могу продемонстрировать, как легко это может сделать нетехнический пользователь с помощью выбранного мной инструмента - Magnus (входит в Potens.io - Набор инструментов для BigQuery)

Ниже приведен снимок рабочего процесса Magnus с двумя задачами BigQuery, которые воспроизводят точно описанные выше шаги

enter image description here

Как вы можете видеть здесь:

В первой задаче мы генерируем оператор с ожидаемыми сопоставленными именами столбцов и присваиваем результат параметру с именем var_columns_list (после выполнения рабочего процесса он получит ожидаемое значение)

enter image description here

Во второй Задаче мы просто строим динамический sql, используя этот параметр

Также вы можете заметить, что вместо простой ссылки на таблицы типа project.dataset.Table1 и project.dataset.Mappingtable - я использую <var_project_dataset>.Table1 и <var_project_dataset>.Mappingtable, а параметр var_project_dataset устанавливается на панели параметров

После запуска этого рабочего процесса мы получаем ожидаемый результат, как показано ниже

enter image description here

Пока до казни было

enter image description here

Очевидно, что это упрощенный пример, и он будет работать КАК ЕСТЬ, только если у вас есть базовые типы столбцов - без структур и массивов. Тем не менее, хорошая новость заключается в том, что этот подход будет легко обрабатывать 200 или более столбцов, которые вы упомянули в своем вопросе.

В любом случае, я думаю, что приведенный выше пример может стать хорошим началом для вас!

Раскрытие информации: я являюсь автором и руководителем команды Potens.io, что отражено в моем профиле. Я также являюсь экспертом Google Developer по облачной платформе и являюсь автором расширения BigQuery Mate Chrome

...