Слияние таблиц BigQuery

Оператор MERGE позволяет актуализировать данные одной таблицы данными из другой, совмещая функционал UPDATE, INSERT и DELETE. Полезно применять в случае, когда требуется обновить часть данных агрегированной таблицы без необходимости сводить заново весь массив данных.

Синтаксис:

MERGE `project_name.dataset.target_table` [[AS] %alias%]
USING `project_name.dataset.source_table` [[AS] %alias%]
ON %conditions%
WHEN MATCHED [AND %search_filter%] THEN (UPDATE|DELETE)
WHEN NOT MATCHED [BY TARGET] [AND %search_filter%] THEN INSERT
WHEN NOT MATCHED BY SOURCE [AND %search_filter%] THEN (UPDATE|DELETE)

В первой строке задается путь к целевой таблице.

Во второй — путь к исходной таблице или подзапрос SELECT. Рекомендуется использовать псевдонимы для таблиц %alias%, в случае они имеют совпадающие схемы.

Далее следует логическое выражение сравнения — столбцы таблиц, по которым происходит сопоставление. В зависимости от комбинаций условий WHEN Меняется тип сопоставления.

Следующий блок инструкций может описывать три ситуации: когда выражение сравнение ИСТИНА MATCHED, когда ЛОЖЬ по цели NOT MATCHED BY TARGET и когда выражение ЛОЖЬ по источнику NOT MATCHED BY SOURCE. Для корректного выполнения запроса необходимо и достаточно наличие хотя бы одной инструкций из трех.

WHEN MATCHED [AND %search_filter%] THEN (UPDATE|DELETE) — описание операции обновления UPDATE или удаления DELETE строк целевой таблицы, выполняемых в случае, когда выполняется условие сравнения. Опционально может содержать условие фильтрации [AND %search_filter%]. В случае, если требуется выполнить обновление строки, необходимо обеспечить уникальность сопоставляемых строк в исходной таблице/подзапросе (целевой строке(-ам) должна соответствовать только одна исходная строка).

WHEN NOT MATCHED [BY TARGET] [AND %search_filter%] THEN INSERT — если условие сравнения не выполнено по цели (в целевой таблице не найдета строка из исходной), то выполняется вставка строки INSERT. Инструкцию [BY TARGET] можно опустить.

WHEN NOT MATCHED BY SOURCE [AND %search_filter%] THEN (UPDATE|DELETE) — описание операций обновления UPDATE или удаления DELETE строк целевой таблицы для тех случаев, когда для них не удалось найти соответствующие строки в исходной таблице.

Примеры запросов. Работа с двумя таблицами.

Целевая таблица target_table

id name quantity price cost
1Телефон5nullnull
2Телевизор20nullnull
3Монитор10nullnull
4Фен2nullnull
5Холодильник5nullnull

Исходная таблица source_table

id price
110.00
245.00
313.40
48.00
6100.00
777.00

Задача: проставить корректные значения цены price и общей стоимости cost товаров целевой таблицы

MERGE `project_name.dataset.target_table` AS A
USING `project_name.dataset.source_table` AS B
ON A.ID = B.ID
WHEN MATCHED THEN UPDATE SET price = B.price, cost = quantity * B.price

Результат:

id name quantity price cost
1Телефон510.0050.00
2Телевизор2045.00900.00
3Монитор1013.40134.00
4Фен28.0016.00
5Холодильник5nullnull

Задача: проставить корректные значения цены price и общей стоимости cost товаров целевой таблицы и удалить строки, для которых цена неизвестна

MERGE `project_name.dataset.target_table` AS A
USING `project_name.dataset.source_table` AS B
ON A.ID = B.ID
WHEN MATCHED THEN 
	UPDATE SET price = B.price, cost = quantity * B.price
WHEN NOT MATCHED BY SOURCE THEN 
	DELETE

Результат:

id name quantity price cost
1Телефон510.0050.00
2Телевизор2045.00900.00
3Монитор1013.40134.00
4Фен28.0016.00

Задача: проставить корректные значения цены price и общей стоимости cost для Телефона и Телевизора и добавить строку с идентификатором id=6 и NULL-значениями в неизвестных ячейках.

MERGE `project_name.dataset.target_table` AS A
USING `project_name.dataset.source_table` AS B
ON A.ID = B.ID
WHEN MATCHED AND A.name = 'Телефон' OR A.Name = 'Телевизор' THEN 
	UPDATE SET price = B.price, cost = quantity * B.price
WHEN NOT MATCHED AND B.id = '6' THEN
	INSERT (id, name, quantity, price, cost) VALUERS (B.id, null, null, B.price, null)

Результат:

id name quantity price cost
1Телефон510.0050.00
2Телевизор2045.00900.00
3Монитор10nullnull
4Фен2nullnull
5Холодильник5nullnull
6nullnull100.00null

Примеры запросов. Модификация одной таблицы (использование подзапросов).

Целевая таблица target_table

idnamequantitypricecost
1Телефон510.00null
2Телевизор2045.00null
3Монитор1013.40null
4Фен28.00null
5Холодильник525.00null

Задача: удалить из таблицы товары количеством меньше 5, для оставшихся определить итоговую стоимость.

MERGE `project_name.dataset.target_table` A
USING (SELECT * FROM `project_name.dataset.target_table` WHERE quantity > 5) B
ON A.ID = B.ID
WHEN MATCHED THEN 
	UPDATE SET cost = quantity * B.price
WHEN NOT MATCHED THEN
	DELETE

Результат:

idnamequantitypricecost
2Телевизор2045.00null
3Монитор1013.40null

Целевая таблица target_table

idnamequantityprice
1Телефон510.00
1null410.00
2Телевизор2045.00
3Монитор1013.40
4Фен28.00
5Холодильник525.00
4null668.00

Задача: присвоить верные названия для товаров, уже имеющихся в таблице

MERGE
`project_name.dataset.target_table` A
USING (SELECT id AS id, name AS name FROM `project_name.dataset.target_table` WHERE name IS NOT NULL GROUP BY id, name) B
ON A.id = B.id
WHEN MATCHED AND name IS NULL THEN
	UPDATE SET name = name * B.name

Результат:

idnamequantityprice
1Телефон510.00
1Телефон410.00
2Телевизор2045.00
3Монитор1013.40
4Фен28.00
5Холодильник525.00
4Фен668.00

AliExpress WW