Ich weiß, dass es einige Posts zum Thema Pivotieren gibt, die ich benutzt habe, um dorthin zu gelangen, wo ich heute bin (Danke an die BQ-Community!). Aber dieser Beitrag sucht nach einem Ratschlag zur Optimierung, wo eine große Anzahl von Pivot-Spalten benötigt wird, verteilte Tabellen-Joins benötigt werden ... sowie Deduplizierung. Nicht viel richtig zu fragen!BigQuery - Joining und Pivotieren von großen Tischen
Ziel:
Wir haben 2 große BQ Tabellen, mit einer vollen 10 Jahren Geschichte, die Verbindung muss:
sales_order_header (13 GB - 1,35 Millionen Zeilen) sales_order_line (50 g - 5 Millionen Zeilen)
Dies ist eine typische "Kopfzeile/Zeile" eins zu viele Beziehung. Die Daten für die Tabellen kommen als 2 separate Streams leider eher als 1 Dokumentart, wo die Zeile innerhalb der Kopfzeile verschachtelt ist, was ideal wäre - aber ihre nicht so verteilten Joins werden für einige der Ansichten notwendig, die unser BI-Tool (Tableau) benötigt in regelmäßigen Abständen (alle 60 Minuten) nennen gereinigt 'Daten aufnehmen, die:
- deduped (beide Tabellen, die sind)
- verbunden Header (auf SalesOrderID) auszukleiden
- jeder seine eigene Array' sourceData 'namve/value paris, das entpackt werden muss /' pivot ', so dass es kein Array ist
Punkt 3 stellt ein eigenes Problem dar. Wir haben eine Spalte mit dem Namen 'sourceData', die im Grunde die Kerndaten ist - ein Array von Stringnamen-Wertpaaren (eine Zeile in BQ ist eine Replikation einer einzelnen Zeile von einem DB, also der Schlüssel ist ein Spaltenname und Wert der Wert für eine einzelne Zeile).
Jetzt denke ich hier das Problem zu lösen, da es 250 Array-Einträge gibt (wir kennen die genaue Anzahl vorne), dies entspricht 250 'unnest' Anweisungen und den besten Ansatz benutzend, den ich Subselects verwenden kann:
(SELECT val FROM UNNEST (Source) WHERE name = 'a') AS a, 250 mal
und das als Muster für jeden der Header und die Linie Tabellen Ansichten repsective getan.
So ist die SQL für die Ansicht zum Abrufen nur eines deduktiven, flatternd/geschwenkt Array für die Tabelle Sales_order_header wie folgt. Die sales_order_line hat das gleiche Muster für seine Ansicht:
#standardSQL
WITH latest_snapshot_dups AS (
SELECT
salesOrderId,
PARSE_TIMESTAMP("%Y-%m-%dT%H:%M:%E*S%Ez", lastUpdated) AS lastUpdatedTimestampUTC,
sourceData,
_PARTITIONTIME AS bqPartitionTime
FROM
`project.ds.sales_order_header_refdata`
),
latest_snapshot_nodups AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY salesOrderId ORDER BY lastUpdatedTimestampUTC DESC) AS rowNum
FROM latest_snapshot_dups
)
SELECT
salesOrderId,
lastUpdatedTimestampUTC,
(SELECT val FROM UNNEST(sourceData) WHERE name = 'a') AS a,
(SELECT val FROM UNNEST(sourceData) WHERE name = 'b') AS b,
....250 of these
FROM
latest_snapshot_nodups
WHERE
rowNum = 1
Obwohl nur ein hier zeigen, haben wir diese zwei ähnliche Ansichten (mit insgesamt 250 + 300 = 550 einzigartige Unterabfragen, die UNNEST/Pivot), und jetzt will ich Um den Header mit den Zeilenansichten zu verbinden, stoße ich sofort auf ein Problem, das eine Grenze von Unterabfragen überschreitet.
Gibt es einen besseren Weg, dies zu tun, vorausgesetzt, dass dies die Daten sind, mit denen zu arbeiten ist? Ein besserer Weg, um vielleicht "zu drehen"? Oder eine effizientere Möglichkeit, eine einzelne Ansicht zu erstellen, die die Reihenfolge der Dinge optimiert, anstatt zwei separate Ansichten zu verwenden?
Vielen Dank für Ihre Hilfe BQ Gemeinschaft!
super danke Mikhail, werde das sehr gerne ausprobieren! Eine Sache - ich kann die Verwendung einer groupBy sehen, ich habe tatsächlich etwa 10 andere Spalten, die ich in der Projektion sowie nicht nur salesOrderId in der groupBy-Anweisung (z. B. eine Reihe von Daten und eine externe ID) verwendet würde. Schränkt dies die groupBy als Option ein? –
sollten Sie nur alle Gruppierungsspalten in die GROUP BY-Anweisung aufnehmen. Beispiel: GROUP BY salesOrderId, lastUpdatedTimestampUTC –