2016-07-18 3 views
0

Мы используем BigQuery религиозно и имеем две таблицы, которые по существу обновлялись параллельно с помощью разных процессов. Проблема, которую я имею, у нас нет уникального идентификатора для таблиц, и цель состоит в том, чтобы объединить две таблицы с нулевым дублированием, если это возможно. Уникальный идентификатор состоит из двух столбцов.BigQuery DeDuplication на двух столбцах как уникальный ключ

Я пробовал различные MySQL-запросы, но ни один из них не работает в BigQuery. Поэтому я отправляю здесь помощь. :)

Шаг 1. Скопируйте «чистый» стол в новый объединенный стол.

Шаг 2. Запросите «грязную» (старую) таблицу и вставьте любые отсутствующие записи.

Запрос Попытка 1:

SELECT 
    COUNT(c.*) 
FROM 
    [flash-student-96619:device_data.device_datav3_20160530] AS old 
WHERE NOT EXISTS (
    SELECT 
    1 
    FROM 
    [flash-student-96619:device_data_v7_merged.20160530] AS new 
    WHERE 
    new.dsn = old.dsn 
    AND new.timestamp = old.timestamp 
) 

Ошибка: ошибка при: 6,1 - 10,65. За один раз может быть выполнен только один запрос.

Запрос Покушение 2:

SELECT 
    * 
FROM 
    [flash-student-96619:device_data.device_datav3_20160530] 
WHERE 
    (dsn, timestamp) NOT IN (
    SELECT 
    dsn, 
    timestamp 
    FROM 
    [flash-student-96619:device_data_v7_merged.20160530] 
) 

Ошибка: Обнаружен "",»», "" в строке 6, колонка 7. Ожидал: ")" ...

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

Любая помощь?

ответ

1

Нечто подобное ниже, должны работать

SELECT * 
FROM (
    SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY dsn, timestamp) AS dup 
    FROM 
    [flash-student-96619:device_data.device_datav3_20160530], 
    [flash-student-96619:device_data_v7_merged.20160530] 
) 
WHERE dup = 1 

Я рекомендую использовать явный список полей вместо * в наружный ВЫБРАТЬ, так что вы можете опустить DUP от фактического выхода

+0

Что около двух таблиц, хотя. Я не хочу обманывать один стол, а другой стол. Наверное, я могу писать в таблицу, а затем переписывать в таблицу ... – Dovy

+0

это было направлено: o) - в любом случае добавлена ​​вторая таблица - идея состоит в том, чтобы дедуплировать комбинированные данные (из обеих таблиц) и записывать их в окончательный чистый стол. надеюсь, это то, что вы хотели достичь. –

+0

Ты в огне мой друг. – Dovy

1

Немного поздно, но я хотел бы отметить что ваш исходный запрос работает с незначительными изменениями, используя standard SQL (снимите флажок «Использовать устаревший SQL» в разделе «Параметры отображения»). Мне просто нужно было изменить new на что-то еще, так как это зарезервированное ключевое слово. Например, этот запрос является действительным:

WITH OldData AS (
    SELECT 
    x AS dsn, 
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp 
    FROM UNNEST([1, 2, 3, 4]) AS x), 
NewData AS (
    SELECT 
    x AS dsn, 
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp 
    FROM UNNEST([5, 2, 1, 6]) AS x) 
SELECT 
    COUNT(*) 
FROM OldData oldData 
WHERE NOT EXISTS (
    SELECT 1 
    FROM NewData newData 
    WHERE 
    newData.dsn = oldData.dsn 
    AND newData.timestamp = oldData.timestamp 
); 
+-----+ 
| f0_ | 
+-----+ 
| 2 | 
+-----+ 

В связи с вашей второй попытки, вы можете сделать:

WITH OldData AS (
    SELECT 
    x AS dsn, 
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp 
    FROM UNNEST([1, 2, 3, 4]) AS x), 
NewData AS (
    SELECT 
    x AS dsn, 
    TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL x HOUR) AS timestamp 
    FROM UNNEST([5, 2, 1, 6]) AS x) 
SELECT 
    * 
FROM OldData 
WHERE 
    STRUCT(dsn, timestamp) NOT IN (
    SELECT AS STRUCT 
    dsn, 
    timestamp 
    FROM NewData); 
+-----+---------------------+ 
| dsn |  timestamp  | 
+-----+---------------------+ 
| 3 | 2016-07-21 11:54:08 | 
| 4 | 2016-07-21 10:54:08 | 
+-----+---------------------+