So generiert Looker SQL

Wenn Sie mit SQL vertraut sind, möchten Sie wahrscheinlich wissen, wie Looker SQL generiert. Looker ist im Grunde ein Tool, das SQL-Abfragen generiert und an eine Datenbankverbindung sendet. Looker formuliert SQL-Abfragen basierend auf einem LookML-Projekt, das die Beziehung zwischen Tabellen und Spalten in der Datenbank beschreibt. Wenn Sie wissen, wie Looker Abfragen generiert, können Sie besser nachvollziehen, wie Ihr LookML-Code in effiziente SQL-Abfragen umgewandelt wird.

Jeder LookML-Parameter steuert einen Aspekt der SQL-Generierung in Looker, indem er die Struktur, den Inhalt oder das Verhalten der Abfrage ändert. Auf dieser Seite werden die Prinzipien beschrieben, nach denen Looker SQL generiert. Alle LookML-Elemente werden jedoch nicht ausführlich behandelt. Die LookML-Kurzübersicht ist ein guter Ausgangspunkt für Informationen zu LookML-Parametern.

Abfrage ansehen

In einem gespeicherten Look oder in einem Explore können Sie auf dem Tab SQL im Bereich Daten sehen, was Looker an die Datenbank sendet, um die Daten abzurufen. Sie können auch die Links In SQL Runner öffnen und In SQL Runner erläutern unten auf dem Tab SQL verwenden, um die Abfrage in SQL Runner oder den Erläuterungsplan der Datenbank für die Abfrage aufzurufen.

Weitere Informationen zu SQL Runner finden Sie auf der Dokumentationsseite SQL Runner-Grundlagen. Weitere Informationen zur Optimierung einer Abfrage mit SQL Runner finden Sie im Communitybeitrag SQL mit EXPLAIN optimieren.

Kanonische Form einer Looker-Abfrage

SQL-Abfragen in Looker haben immer die folgende Form.

SELECT
   <dimension>, <dimension>, ...
   <measure>, <measure>, ...
FROM <explore>
LEFT JOIN <view> ON ...
LEFT JOIN <view> ON ...
WHERE (<dimension_filter_expression>) AND (<dimension_filter_expression>) AND ...
GROUP BY <dimension>, <dimension>, <dimension>, ...
HAVING <measure_filter_expression> AND <measure_filter_expression> AND ...
ORDER BY <dimension> | <measure>
LIMIT <limit>

Im LookML-Projekt werden alle Dimensionen, Messwerte, Explores und Ansichten definiert, auf die in der SQL-Abfrage verwiesen wird. Filterausdrücke werden vom Nutzer in Looker angegeben, um Ad-hoc-Abfragen zu erstellen. Filterausdrücke können auch direkt in der LookML-Datei deklariert werden, um auf alle Abfragen angewendet zu werden.

Grundlegende Komponenten einer Looker-Abfrage

Alle Looker-Abfragen werden durch diese grundlegenden Parameter dargestellt, die auf ein LookML-Projekt angewendet werden, wie in der vorherigen Beispielabfrage zu sehen.

Looker verwendet die folgenden Parameter, um eine vollständige SQL-Abfrage zu generieren:

  • model: Der Name des LookML-Modells, auf das ausgerichtet werden soll. Hier wird die Zieldatenbank angegeben.
  • explore: Der Name des zu abfragenden explorativen Datenanalysetools, der die SQL-Klausel FROM ausfüllt
  • Felder: Die Parameter dimension und measure, die in die Abfrage aufgenommen werden und die SQL-SELECT-Klausel ausfüllen
  • filter: Looker-Filterausdrücke, die auf null oder mehrere Felder angewendet werden, die die SQL-Klauseln WHERE und HAVING füllen
  • Sortierreihenfolge: das Feld, nach dem sortiert werden soll, und die Sortierreihenfolge, die die SQL-ORDER BY-Klausel füllt

Diese Parameter sind genau die Elemente, die ein Nutzer beim Erstellen einer Abfrage auf der Looker-Seite Explore angibt. Diese Elemente werden in allen Modi zur Ausführung von Abfragen mit Looker angezeigt, z. B. im generierten SQL, in der URL, die die Abfrage darstellt, und in der Looker API.

Was ist mit den Ansichten, die in den LEFT JOIN-Klauseln angegeben sind? JOIN-Klauseln werden basierend auf der Struktur des LookML-Modells ausgefüllt, in dem festgelegt ist, wie Ansichten mit Explores zusammengeführt werden. Beim Erstellen von SQL-Abfragen werden in Looker nur bei Bedarf JOIN-Klauseln eingefügt. Wenn Nutzer in Looker eine Abfrage erstellen, müssen sie nicht angeben, wie Tabellen zusammengeführt werden, da diese Informationen im Modell codiert sind. Dies ist einer der größten Vorteile von Looker für Geschäftsnutzer.

Beispielabfrage und die resultierende SQL-Abfrage

Erstellen wir eine Abfrage in Looker, um zu veranschaulichen, wie die Abfrage gemäß dem vorherigen Muster generiert wird. Angenommen, Sie haben einen E-Commerce-Shop mit einer Datenbank mit zwei Tabellen, orders und users, um Nutzer und Bestellungen zu verfolgen.

orders
id INT
created_at DATETIME
users_id INT
status VARCHAR(255)
traffic_source VARCHAR(15)
users
id INT
email VARCHAR(255)
first_name VARCHAR(255)
last_name VARCHAR(255)
created_at DATETIME
zip INT
country VARCHAR(255)
state VARCHAR(255)
city VARCHAR(255)
age INT
traffic_source VARCHAR(15)

Wir möchten die Anzahl der Bestellungen (ORDERS Count) nach Bundesland (USERS State) gruppieren und nach dem Erstellungsdatum der Bestellung (ORDERS Created Date) filtern.

In einer explorativen Datentabelle sehen Sie die Anzahl der Bestellungen, die in den letzten 30 Tagen aufgegeben wurden. Die Bestellungen sind nach Nutzerstatus gruppiert.

Wenn Sie die SQL-Abfrage sehen möchten, die von Looker generiert und ausgeführt wird, klicken Sie im Bereich Daten auf den Tab SQL.

SELECT COALESCE(users.state, ' ') AS "_g1",
   users.state AS 'users.state',
   COUNT(DISTINCT orders.id) AS 'orders.count'
FROM orders
LEFT JOIN users ON orders.user_id = users.id

WHERE
  orders.created_at BETWEEN (CONVERT_TZ(DATE_ADD(CURDATE(), INTERVAL -29 day), 'America/Los_Angeles', 'UTC',)) AND (CONVERT_TZ(DATE_ADD(DATE_ADD(DATE_ADD(CURDATE(), INTERVAL -29 day), INTERVAL 30 day), INTERVAL -1 second), 'America/Los_Angeles', 'UTC'))
GROUP BY 1
ORDER BY COUNT(DISTINCT orders.id) DESC
LIMIT 500

Beachten Sie die Ähnlichkeit mit der Formel für kanonische Suchanfragen. Der Looker SQL-Code weist einige Merkmale von maschinengeneriertem Code auf (z. B. COALESCE(users.state,'') AS "_g1"), entspricht aber immer der Formel.

Probieren Sie weitere Abfragen in Looker aus, um sich zu vergewissern, dass die Abfragestruktur immer gleich ist.

SQL-Code im SQL Runner von Looker ausführen

Looker bietet die Funktion SQL Runner, mit der Sie beliebige SQL-Abfragen auf die in Looker eingerichteten Datenbankverbindungen ausführen können.

Da jede von Looker generierte Abfrage zu einem vollständigen, funktionsfähigen SQL-Befehl führt, können Sie die Abfrage mit SQL Runner untersuchen oder damit experimentieren.

Für die Ausführung in SQL Runner generierte SQL-Abfragen liefern dasselbe Ergebnis. Wenn der SQL-Code Fehler enthält, hebt SQL Runner die Position des ersten Fehlers im SQL-Befehl hervor und gibt die Position des Fehlers in der Fehlermeldung an.

Suchanfragekomponenten in der erweiterten URL prüfen

Nachdem Sie eine Abfrage in Looker ausgeführt haben, können Sie die erweiterte URL prüfen, um die grundlegenden Komponenten einer Looker-Abfrage zu sehen. Wählen Sie im Zahnradmenü von „Explore“ die Option Teilen aus, um das Menü URLs teilen zu öffnen.

Die erweiterte URL enthält genügend Informationen, um die Suchanfrage neu zu erstellen. In diesem Beispiel für eine erweiterte URL werden beispielsweise folgende Informationen angezeigt:

https://<Looker instance URL>.cloud.looker.com/explore/e_thelook/events?fields=users.state,users.count
&f[users.created_year]=2020&sorts=users.count+desc&limit=500
Modell e_thelook
analysieren events
Felder, die abgefragt und angezeigt werden sollen fields=users.state,users.count
Sortierfeld und -reihenfolge sorts=users.count+desc
Filterfelder und -werte f[users.created_year]=2020

So werden JOINs in Looker strukturiert

In der vorangehenden Beispielabfrage wird das orders-Explore in der Hauptklausel FROM und die zusammengeführten Ansichten in den LEFT JOIN-Klauseln angezeigt. Looker-Joins können auf viele verschiedene Arten geschrieben werden. Weitere Informationen finden Sie auf der Seite Mit Joins in LookML arbeiten.

In SQL-Blöcken werden benutzerdefinierte SQL-Klauseln angegeben.

Nicht alle Elemente einer Looker-Abfrage werden automatisch generiert. Irgendwann muss das Datenmodell bestimmte Details bereitstellen, damit Looker auf die zugrunde liegenden Tabellen zugreifen und abgeleitete Werte berechnen kann. In LookML sind SQL-Blöcke SQL-Code-Snippets, die vom Datenmodellierer bereitgestellt werden und mit denen in Looker vollständige SQL-Ausdrücke erstellt werden.

Der gängigste SQL-Blockparameter ist sql. Er wird in Dimensions- und Messwertdefinitionen verwendet. Mit dem Parameter sql wird eine SQL-Klausel angegeben, um auf eine zugrunde liegende Spalte zu verweisen oder eine Aggregatfunktion auszuführen. Im Allgemeinen erwarten alle LookML-Parameter, die mit sql_ beginnen, irgendeine Art von SQL-Ausdruck. Beispiele: sql_always_where, sql_on und sql_table_name. Weitere Informationen zu den einzelnen Parametern finden Sie in der LookML-Referenz.

Beispiele für SQL-Blöcke für Dimensionen und Messwerte

Im folgenden Codebeispiel finden Sie einige Beispiele für SQL-Blöcke für Dimensionen und Messwerte. Der LookML-Substitutionsoperator ($) kann bewirken, dass diese sql-Deklarationen fälschlicherweise nicht wie SQL wirken. Doch nach einer Substitution ist die daraus resultierende Zeichenfolge reines SQL, das Looker in die SELECT-Klausel der Abfrage einfügt.

dimension: id {
  primary_key: yes
  sql: ${TABLE}.id ;;  # Specify the primary key, id
}
measure: average_cost {
  type: average
  value_format: "0.00"
  sql: ${cost} ;;      # Specify the field that you want to average
                       # The field 'cost' is declared elsewhere
}
dimension: name {
  sql: CONCAT(${first_name}, ' ', ${last_name}) ;;
}
dimension: days_in_inventory {
  type: number
  sql: DATEDIFF(${sold_date}, ${created_date}) ;;
}

Wie in den letzten beiden Dimensionen in diesem Beispiel zu sehen, können SQL-Blöcke Funktionen verwenden, die von der zugrunde liegenden Datenbank unterstützt werden (z. B. die MySQL-Funktionen CONCAT und DATEDIFF in diesem Fall). Der Code, den Sie in SQL-Blöcken verwenden, muss dem von der Datenbank verwendeten SQL-Dialekt entsprechen.

Beispiel für einen SQL-Block für abgeleitete Tabellen

Abgeleitete Tabellen verwenden ebenfalls einen SQL-Block, um die Abfrage zur Ableitung der Tabelle anzugeben. Hier ein Beispiel für eine SQL-basierte abgeleitete Tabelle:

view: user_order_facts {
  derived_table: {
    sql:
      SELECT
        user_id
        , COUNT(*) as lifetime_orders
      FROM orders
      GROUP BY 1 ;;
  }

  # later, dimension declarations reference the derived column(s)…
  dimension: lifetime_orders {
    type: number
  }
}

Beispiel für einen SQL-Block zum Filtern eines Explores

Mit den LookML-Parametern sql_always_where und sql_always_having können Sie die für eine Abfrage verfügbaren Daten einschränken, indem Sie einen SQL-Block in die WHERE- oder HAVING-Klausel der SQL-Abfrage einfügen. In diesem Beispiel wird mit dem LookML-Ersetzungsoperator ${view_name.SQL_TABLE_NAME} auf eine abgeleitete Tabelle verwiesen:

explore: trips {
  view_label: "Long Trips"
  # This will ensure that we only see trips that are longer than average!
  sql_always_where: ${trips.trip_duration}>=(SELECT tripduration FROM ${average_trip_duration.SQL_TABLE_NAME});;
}