SQL-Konzepte für Joins

Wie in SQL wird in LookML ein Join verwendet, um Zeilen aus zwei oder mehr Tabellen basierend auf einer dazwischenliegenden Spalte zu kombinieren.

In LookML wird ein Explore – wie vom LookML-Parameter explore definiert – verwendet, um festzulegen, wie ein Nutzer die Daten abfragen kann. Ein Explore besteht aus mindestens einer Ansicht oder mehreren Ansichten, die miteinander verknüpft sind. Die Hauptansicht im Explore ist immer in der Abfrage enthalten. Die zusammengeführten Datenansichten werden normalerweise nur eingeschlossen, wenn sie für die Abfrage erforderlich sind.

Eine LookML-Ansicht entspricht einer SQL-Tabelle (oder einem anderen Element mit der Struktur einer Tabelle) in der Datenbank oder einer abgeleiteten Tabelle. In der Ansicht wird festgelegt, welche Felder oder Spalten in der Datenbank verfügbar sind und wie darauf zugegriffen werden soll.

Das folgende Beispiel ist eine Definition für die explorative Datenanalyse orders.

explore: orders {
  join: users {
    type: left_outer
    sql_on: ${orders.user_id} = ${users.id} ;;
    relationship: many_to_one
  }
}

Die Ansicht orders, die die Hauptansicht im Explore ist, wird mit der Ansicht users über eine SQL LEFT OUTER JOIN verbunden, wie durch den LookML-Parameter type: left_outer angegeben. In der SQL ON-Klausel, die durch den sql_on-LookML-Parameter definiert wird, wird nicht table_alias.column verwendet, sondern stattdessen to ${view_name.field_name}. Wenn sich also der Tabellen- oder Spaltenname in der Datenbank ändert, muss diese Änderung nur an einer Stelle vorgenommen werden.

Der Parameter relationship ist wichtig. Joins können zu Fanout-Problemen führen, wenn Zeilen dupliziert werden. Durch die Angabe, dass viele Aufträge mit nur einem Benutzer verknüpft werden, erkennt Looker, dass bei diesem Join keine Fanouts stattfinden, sodass keine besondere Behandlung erforderlich ist. one_to_many-Beziehungen können jedoch eine Verzweigung auslösen.

Bei der automatischen Erstellung von Ansichten und Explores wird standardmäßig ein Left Outer Join verwendet. Im vorherigen Beispiel ist es jedoch sehr wahrscheinlich, dass jeder Auftrag genau einen Nutzer hat, sodass der Join in diesem Beispiel ein Inner Join sein kann.

Wenn Sie sich das generierte SQL-Statement eines Explores ansehen möchten, können Sie das Explore in der Benutzeroberfläche ausführen und dann im Bereich Daten den Tab SQL auswählen.

Wenn Sie beispielsweise das zuvor definierte Explore Orders (Aufträge) öffnen und dann die Felder User ID und Count auswählen, sieht der generierte SQL-Code so aus:

SELECT
    `user_id` AS `orders.user_id`,
    COUNT(*) AS `orders.count`
FROM
    `thelook`.`orders` AS `orders`
GROUP BY
    1
ORDER BY
    2 DESC
LIMIT 500

In diesem Beispiel wird überhaupt nicht auf die Tabelle „users“ verwiesen. Sie wird nur bei Bedarf hereingeholt.

Wenn Sie die Dimension User ID entfernen und die Dimension ID aus der Ansicht Nutzer hinzufügen, sieht die SQL-Abfrage so aus:

SELECT
    `users`.`id` AS `users.id`,
    COUNT(*) AS `orders.count`
FROM
    `thelook`.`orders` AS `orders`
    INNER JOIN `thelook`.`users` AS `users` ON `orders`.`user_id` = `users`.`id`
GROUP BY
    1
ORDER BY
    2 DESC
LIMIT 500

Da in diesem Fall eine Auswahl aus der Ansicht Nutzer getroffen wurde, ist die Zusammenführung enthalten.

Das folgende Beispiel zeigt LookML in der Explore-Datei orders, die zuvor definiert wurde. Dabei wird ein Join zur Ansicht order_items hinzugefügt:

explore: orders {
  join: users {
    type: inner
    sql_on: ${orders.user_id} = ${users.id} ;;
    relationship: many_to_one
  }
  join: order_items {
    type: inner
    sql_on: ${orders.id} = ${order_items.order_id} ;;
    relationship: one_to_many
  }
}

Wenn Sie jetzt die explorative Datenanalyse Bestellungen in der Benutzeroberfläche öffnen, wird die Ansicht Bestellelemente angezeigt. Wenn Sie die Kennzahl Total Sale Price (Gesamtverkaufspreis) in der Ansicht Order Items (Bestellelemente) zusammen mit der Count (Anzahl) aus Orders (Bestellungen) und der ID (ID) von Users (Nutzer) auswählen, generiert Looker den folgenden SQL-Code:

SELECT
    `users`.`id` AS `users.id`,
    COUNT(DISTINCT orders.id ) AS `orders.count`,
    COALESCE(SUM(`order_items`.`sale_price`), 0) AS `order_items.total_sale_price`
FROM
    `thelook`.`orders` AS `orders`
    INNER JOIN `thelook`.`users` AS `users` ON `orders`.`user_id` = `users`.`id`
    INNER JOIN `thelook`.`order_items` AS `order_items` ON `orders`.`id` = `order_items`.`order_id`
GROUP BY
    1
ORDER BY
    2 DESC
LIMIT 500

In diesem Beispiel wurde COUNT(*) AS orders.count zu COUNT(DISTINCT orders.id ) AS orders.count. Looker hat ein mögliches Fanout erkannt und der Funktion SQL COUNT automatisch das Schlüsselwort SQL DISTINCT hinzugefügt.