Обновление BigQuery, где условие WHERE имеет несколько строк (Limit Update) - PullRequest
0 голосов
/ 30 апреля 2020

У меня проблема при попытке сопоставить данные из таблицы с данными из другой таблицы в Google BigQuery. Для простоты: у меня есть dataTable с колонкой data_modelname, data_version, data_date. mappingTable содержит mapping_modelname, mapping_version, mapping_date.

Когда я пробую этот код,

UPDATE dataTable
SET
    dataTable.data_date = mappingTable.data_date,
    dataTable.data_version = mappingTable.data_version

FROM mappingTable
WHERE 
    LOWER(data_modelname) IN (
    SELECT DISTINCT LOWER(mapping_modelname) AS distinctModel
    FROM mappingTable 
    WHERE mappingTable.data_version IS NOT NULL 
    )

Я получаю следующее сообщение об ошибке от BigQuery:

UPDATE / MERGE должно совпадать не более чем с одной исходной строкой для каждой целевой строки

Оператор выбора различных значений возвращает список из ~ 300 различных моделей. Таким образом, при рассмотрении условия WHERE, будет только один результат, где, например, LOWER (data_modelname) равен LOWER (ABC123).

К сожалению, мой mappingTable содержит более одной записи на модель (дубликаты), но я хочу только первую найденную запись. Updating with LIMIT 1 не работает. Я также попробовал этот код с таблицей сопоставления с меньшим количеством записей и, следовательно, без дубликатов. Это сработало хорошо. Тем не менее, он возвращает ту же ошибку, когда существует более одного имени модели.

WHERE LOWER(data_modelname) = LOWER(mapping_modelname)

Не могли бы вы помочь мне вставить (обновить) из mappingTable.data_date и mappingTable.data_version из mapping table в data table w here the data_modelname is mapping_modelname. Далее было бы здорово быть возможность использовать некоторые шаблоны или регулярные выражения для отображения имен моделей, например, WHERE LOWER (data_modelname) IS LIKE "% mapping_modelname%".

Большое спасибо.


Редактировать, новая проблема:

Теперь я столкнулся с другой проблемой. Та же ситуация и с таблицами, но теперь мне нужно обновить поле data_date_Installed, где модель и data_version_Installed совпадают. Так что в моем data-table есть поле версии "3.4" и data_model "ABC123". В mapping-table есть также mapping_model "ABC123" и много разных версий в mapping_version_Installed, и, конечно, также «3.4» и соответствующая дата этой версии в поле mapping_date_installed. Я пробовал этот код, однако он соответствует только 88 значениям из 1m.

UPDATE dataTable dt
    SET dt.data_date_installed = mapping_date_installed,
    FROM (SELECT ARRAY_AGG(mt LIMIT 1)[ORDINAL(1)].*
          FROM mappingTable mt
          WHERE mt.data_installed_version IS NOT NULL
          GROUP BY LOWER(mt.mapping_modelname)
         ) mt
    WHERE LOWER(mt.mapping_modelname) = LOWER(dt.data_modelname)
    AND
    data_version_Installed = mapping_version_Installed

На самом деле я могу исключить ошибку в таблицах: значения отображения верны, а тип данных также корректен (date = DATE и version = STRING) в обеих таблицах. Кроме того, сравнение строк с LIKE instead of = не привело к более подходящим значениям. Возможно, в GROUP BY statement пропущено много возможных установленных_версий.

Я очень рад и благодарен, если у вас есть совет.

Редактировать, решено:

Можно было использовать проблему с простым SQL ГДЕ:

WHERE LOWER(mt.mapping_model) = LOWER(FINAL_modelName)
AND
data_date_installed = mt.mapping_date_installed

1 Ответ

0 голосов
/ 30 апреля 2020

Использование агрегации для получения одной строки на LOWER(model_name):

UPDATE dataTable dt
    SET dt.data_date = mt.data_date,
        dt.data_version = mt.data_version
    FROM (SELECT ARRAY_AGG(mt LIMIT 1)[ORDINAL(1)].*
          FROM mappingTable mt
          WHERE mt.data_version IS NOT NULL
          GROUP BY LOWER(mt.mapping_modelname)
         ) mt
    WHERE LOWER(mt.mapping_modelname) = LOWER(dt.data_modelname)
...