2016-04-17 42 views
10

Mam tabelę zawierającą> 1 mln wierszy danych i ponad 20 kolumn.Usuwanie zduplikowanych wierszy z tabeli BigQuery

W ramach mojej tabeli (tabela X) zidentyfikowałem zduplikowane rekordy (~ 80 tys.) W jednej konkretnej kolumnie (kolumna_adresów).

Jeśli to możliwe, chciałbym zachować oryginalną nazwę tabeli i usunąć duplikaty rekordów z mojej problematycznej kolumny, w przeciwnym razie mógłbym utworzyć nową tabelę (tableXfinal) z tym samym schematem, ale bez duplikatów.

Nie jestem biegły w SQL lub innym języku programowania, więc proszę wybaczyć moją niewiedzę.

delete from Accidents.CleanedFilledCombined 
where Fixed_Accident_Index 
in(select Fixed_Accident_Index from Accidents.CleanedFilledCombined 
group by Fixed_Accident_Index 
having count(Fixed_Accident_Index) >1); 
+0

Właśnie przeczytałem, że tabele BigQuery są dołączane tylko dlatego, że potrzebuję zrobić kopię mojego stołu, więc! – TheGoat

Odpowiedz

15

można usunąć duplikaty uruchamiając kwerendę, która przepisuje tabelę (można użyć tej samej tabeli jako cel, czy można utworzyć nową tabelę, aby sprawdzić, czy ma to, czego chcesz, a następnie skopiować go nad starym stołem).

Zapytanie, które powinny pracować jest tutaj:

SELECT * 
FROM (
    SELECT 
     *, 
     ROW_NUMBER() 
      OVER (PARTITION BY Fixed_Accident_Index) 
      row_number 
    FROM Accidents.CleanedFilledCombined 
) 
WHERE row_number = 1 
+0

Wielkie dzięki Jordan. – TheGoat

+1

zobacz poniżej moją odpowiedź na bardziej skalowalną alternatywę z #standardSQL –

+0

Czy można to zrobić za pomocą interfejsu API? –

1

Jeśli schemat nie ma żadnych zapisów - poniżej variation odpowiedzi Jordana będzie działać na tyle dobrze, ze pisanie na tym samym stole lub nową itp

SELECT <list of original fields> 
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Fixed_Accident_Index) AS pos, 
    FROM Accidents.CleanedFilledCombined 
) 
WHERE pos = 1 

W bardziej ogólnym przypadku - ze złożonym schematem z rekordami/polami powiązanymi itd. - powyższe podejście może być wyzwaniem.

Proponuję spróbować użyć interfejsu API Tabledata: insertAll z rows[].insertId ustawionym na odpowiedni Fixed_Accident_Index dla każdego wiersza. W takim przypadku zduplikowane wiersze zostaną usunięte przez BigQuery

Oczywiście będzie to dotyczyło kodu po stronie klienta - może to nie być istotne dla tego konkretnego pytania. I miałaś próbował tego podejścia przez siebie obu, ale czuję to może być ciekawe, aby spróbować: o)

+0

Dzięki Michaelu, kilka razy uratowałeś mi bekon! – TheGoat

+0

Jeśli masz zagnieżdżone/powtórzone pola, zapytanie, o którym wspomniałem powinno działać, o ile ustawisz opcję zapytania, aby umożliwić duże wyniki i zapobiec spłaszczaniu. –

+0

Zamiast listy oryginalnych pól, jeśli używasz standardowego SQL, możesz użyć czegoś takiego jak: SELECT * except (pos) FROM (...) WHERE pos = 1; – killachaos

4

alternatywą dla odpowiedź Jordana - ten skaluje się lepiej, gdy zbyt wielu powtórzeń:

#standardSQL 
SELECT event.* FROM (
    SELECT ARRAY_AGG(
    t ORDER BY t.created_at DESC LIMIT 1 
)[OFFSET(0)] event 
    FROM `githubarchive.month.201706` t 
    # GROUP BY the id you are de-duplicating by 
    GROUP BY actor.id 
) 

lub krótszego Wersja (zajmuje dowolny wiersz, zamiast najnowszego):

SELECT k.* 
FROM (
    SELECT ARRAY_AGG(x LIMIT 1)[OFFSET(0)] k 
    FROM `fh-bigquery.reddit_comments.2017_01` x 
    GROUP BY id 
) 
+0

Cześć Felipe, bardzo fajnie! W związku z ciekawością, w jaki sposób zbudowałbyś zapytanie standardSQL (tylko), które zamiast tego używało "DELETE" DML na tablicy źródłowej lub przepisywanie w celu usunięcia duplikatów? –