Cómo incorporar SQL y hacer referencia a objetos de LookML

Para escribir LookML potente, debes poder hacer referencia a dimensiones, medidas, vistas o tablas derivadas existentes, incluso si no están dentro del alcance actual. También debes hacer referencia a las columnas de la tabla subyacente y usar las llamadas a funciones del dialecto de la base de datos para manipular esos valores.

Operador de sustitución ($)

El operador de sustitución, $, hace que el código de LookML sea más modular y reutilizable, lo que te permite hacer referencia a otras vistas y tablas derivadas, columnas de una tabla de SQL o dimensiones y medidas de LookML. Esto es bueno por dos razones. En primer lugar, es posible que ya hayas elaborado una dimensión o medición muy complicada, y no necesitarás volver a escribir toda la complejidad. Segundo, si cambias algo sobre una dimensión o medida, ese cambio puede propagarse a todo lo que se base en ella.

Existen varias formas de usar el operador de sustitución:

${TABLE}.column_name hace referencia a una columna de la tabla que está conectada a la vista en la que estás trabajando. Por ejemplo:

dimension: customer_id {
  type: number
  sql: ${TABLE}.customer_id ;;
}

${field_name} hace referencia a una dimensión o medición dentro de la vista en la que estás trabajando. Por ejemplo:

measure: total_population {
  type: sum
  sql: ${population} ;;
}

${view_name.field_name} hace referencia a una dimensión o medida de otra vista. Por ejemplo:

dimension: lifetime_orders {
  type: number
  sql: ${user_order_facts.lifetime_orders} ;;
}

${view_name.SQL_TABLE_NAME} hace referencia a otra vista o tabla derivada. Ten en cuenta que SQL_TABLE_NAME en esta referencia es una string literal; no es necesario reemplazarla por nada. Por ejemplo:

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});;
}

${view_name.SQL_TABLE_NAME} no funciona con el parámetro sql_trigger que se usa con los grupos de datos.

Alcance y nombres

Puedes asignar nombres a Exploraciones, vistas, campos y conjuntos. Estos identificadores de Looker se escriben sin comillas.

Los campos y conjuntos de LookML tienen nombres completos y nombres cortos:

  • Los nombres completos tienen el formato <view>.<field-name | set-name>. En el lado izquierdo, se indica el alcance, que es la vista que contiene el campo o el conjunto. En el lado derecho, se especifica el campo particular o el nombre del conjunto.
  • Los nombres cortos simplemente toman el formato <field-name | set-name>, sin período de separación. Looker expande los nombres cortos a nombres completos con el alcance en el que se usan.

A continuación, se incluye un ejemplo que muestra muchas formas de nombres y alcance. Este es un grupo de campos poco realista, pero se muestra para demostrar una variedad de expresiones de alcance posibles.

view: orders {                   # "orders" becomes the containing scope
  measure: count {               # short name, equivalent to orders.count
    type: count
  }
  dimension: customer_id {       # short name, equivalent to orders.customer_id
    type: number
    sql: ${TABLE}.customer_id ;;
  }
  dimension: customer_address {  # short name, equivalent to orders.customer_address
    sql: ${customer.address} ;;  # full name, references a field defined in the "customer" view
  }
  set: drill_fields {            # short name, equivalent to orders.drill_fields
    fields: [
      count,                     # short name, equivalent to orders.count
      customer.id                # full name, references a field defined in the "customer" view
    ]
  }
}

En la declaración dimension: customer_address, ten en cuenta que la vista subyacente del bloque de SQL (customer) es diferente del alcance de la vista contenedora (orders). Esto puede ser útil cuando necesitas comparar campos entre dos vistas diferentes.

Cuando una vista (que denominaremos "vista A") se refiere a un campo definido en una vista diferente (la llamaremos "vista B"), hay algunos aspectos que debes tener en cuenta:

  1. El archivo de la vista B debe incluirse en el mismo modelo que la vista A, mediante el parámetro include.
  2. La vista B debe unirse para poder ver la A en una o más exploraciones. Consulta nuestra página Trabaja con uniones en LookML para obtener más información.

Dialecto de SQL

Looker admite muchos tipos de bases de datos, como MySQL, Postgres, Redshift, BigQuery, etcétera. Cada base de datos admite un conjunto de atributos ligeramente diferente con nombres de funciones distintos, denominado dialecto SQL.

LookML está diseñado para funcionar con todos los dialectos de SQL, y no prefiere un dialecto del otro. Sin embargo, deberás incluir expresiones de código SQL (conocidas como bloques de SQL) en ciertos parámetros de LookML. Con estos parámetros, Looker pasa la expresión en SQL directamente a tu base de datos, por lo que debes usar el dialecto SQL que coincida con tu base de datos. Por ejemplo, si usas una función de SQL, debe ser compatible con tu base de datos.

Bloques de SQL

Algunos parámetros de LookML requieren que proporciones expresiones en SQL sin procesar para que Looker pueda comprender cómo recuperar datos de tu base de datos.

Los parámetros de LookML que comienzan con sql_ esperan una expresión SQL de alguna forma. Algunos ejemplos son sql_always_where, sql_on y sql_table_name. El parámetro más común de LookML para bloques de SQL es sql, que se usa en las definiciones de los campos de dimensión y medición para especificar la expresión en SQL que define la dimensión o la medida.

El código que especificas en un bloque de SQL puede ser tan simple como el nombre de un solo campo o tan complejo como una subselección correlacionada. El contenido puede ser bastante complejo y adaptarse a casi cualquier necesidad que puedas tener de expresar una lógica de consulta personalizada en SQL sin procesar. Ten en cuenta que el código que uses en los bloques de SQL debe coincidir con el dialecto SQL que usa la base de datos.

Ejemplos de bloques de SQL para dimensiones y mediciones

A continuación, se muestran ejemplos de bloques de SQL para dimensiones y mediciones. El operador de sustitución de LookML ($) puede hacer que estas declaraciones sql parezcan engañosamente distintas de SQL. Sin embargo, después de que se produce la sustitución, la cadena resultante es SQL puro, que Looker inserta en la cláusula SELECT de la consulta.

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

Como se muestra en las dos últimas dimensiones, los bloques de SQL pueden usar funciones compatibles con la base de datos subyacente (como las funciones de MySQL CONCAT y DATEDIFF en este ejemplo).

Bloque de SQL de ejemplo con una subselección correlacionada

Puedes colocar cualquier instrucción de SQL en el bloque SQL de un campo, incluida una subselección correlacionada. A continuación, se incluye un ejemplo:

view: customers {
  dimension: id {
    primary_key: yes
    sql: ${TABLE}.id ;;
  }
  dimension: first_order_id {
    sql: (SELECT MIN(id) FROM orders o WHERE o.customer_id=customers.id) ;;
         # correlated subselect to derive the value for "first_order_id"
  }
}

Bloque de SQL de ejemplo para tablas derivadas

Las tablas derivadas usan el bloque de SQL para especificar la consulta que deriva la tabla. A continuación, se incluye un ejemplo:

view: user_order_facts {
  derived_table: {
    sql:            # Get the number of orders for each user
      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
  }
}

Referencias de tipos de campos de LookML

Cuando haces referencia a un campo de LookML existente dentro de otro campo, puedes indicarle a Looker que trate el campo al que se hace referencia como un tipo de datos específico con dos puntos (::) seguidos del tipo deseado. Por ejemplo, si haces referencia a la dimensión orders.created_date dentro de otro campo, puedes usar la sintaxis ${orders.created_date::date} para asegurarte de que el campo created_date se trate como un campo de fecha en SQL que genere Looker, en lugar de convertirse en una cadena.

El tipo de datos que puedes usar en una referencia depende del tipo de datos del campo original al que haces referencia. Por ejemplo, si haces referencia a un campo de cadena, el único tipo de datos que puedes especificar es ::string. Esta es la lista completa de referencias de tipos de campos permitidos que puedes usar para cada tipo de campo:

  • En una referencia a un campo de cadena, puedes usar ::string.
  • En una referencia a un campo numérico, puedes usar ::string y ::number.
  • En una referencia a un campo de fecha u hora, puedes usar ::string, ::date y ::datetime.

    Las referencias que usan ::string y ::date muestran datos en la zona horaria de la consulta, mientras que las que usan ::datetime muestran datos en la zona horaria de la base de datos.
  • En una referencia a un campo yesno, puedes usar ::string, ::number y ::boolean.

    Las referencias de campo que usan el tipo ::boolean no están disponibles para los dialectos de bases de datos que no admiten el tipo de datos booleano.
  • En una referencia a un campo de ubicación, puedes usar ::latitude y ::longitude.

Usa referencias de tipo de campo de LookML con campos de fecha

Como ejemplo, supongamos que tienes una dimensión enrollment_month y una dimensión graduation_month, que se crearon dentro de grupos de dimensiones de type: time. En este ejemplo, el siguiente grupo de dimensiones de type: time produce la dimensión enrollment_month:


dimension_group: enrollment {
  type: time
  timeframes: [time, date, week, month, year, raw]
  sql: ${TABLE}.enrollment_date ;;
}

Del mismo modo, la dimensión graduation_month la crea el siguiente grupo de dimensiones de type: time:


dimension_group: graduation {
  type: time
  timeframes: [time, date, week, month, year, raw]
  sql: ${TABLE}.graduation_date ;;
}

Con las dimensiones enrollment_month y graduation_month, puedes calcular cuántos meses o años transcurrieron entre la inscripción y la graduación de un estudiante creando un grupo de dimensiones de type: duration. Sin embargo, debido a que algunos campos de fecha se convierten como cadenas en el SQL que genera Looker, configurar las dimensiones enrollment_month y graduation_month como los valores de sql_start y sql_end puede generar un error.

Para evitar un error resultante de la conversión de estos campos de tiempo como cadenas, una opción es crear un grupo de dimensiones de type: duration, que haga referencia a los períodos de tiempo raw de los grupos de dimensiones enrollment y graduation en los parámetros sql_start y sql_end:


dimension_group: enrolled {
  type: duration
  intervals: [month, year]
  sql_start: ${enrollment_raw} ;;
  sql_end: ${graduation_raw} ;;
}

En la IU de Explorar, se genera un grupo de dimensiones llamado Duration Enrolled (Duración de la inscripción) con dimensiones individuales Months Enrolled y Years Enrolled.

Una alternativa más simple al uso del período de raw en un grupo de dimensiones de type: duration es especificar el tipo de referencia ::date o ::datetime para los campos a los que se hace referencia en los parámetros sql_start y sql_end.


dimension_group: enrolled {
  type: duration
  intervals: [month, year]
  sql_start: ${enrollment_month::date} ;;
  sql_end: ${graduation_month::date} ;;
}

El LookML de este ejemplo también crea un grupo de dimensiones Duración de la inscripción, pero el uso de la referencia ::date permite usar las dimensiones enrollment_month y graduation_month sin usar un período de tiempo raw ni convertirlas como cadenas con SQL.

Para ver un ejemplo adicional de cómo se pueden usar las referencias de tipo de campo de LookML para crear grupos de dimensiones personalizadas de type: duration, consulta la página de documentación del parámetro dimension_group.

Esta sintaxis no está disponible con medidas de type: list, a las que no se puede hacer referencia a partir de Looker 6.8.

Constantes de LookML

El parámetro constant te permite especificar una constante que puedes usar en todo un proyecto de LookML. Con las constantes de LookML, puedes definir un valor una vez y hacer referencia a él en cualquier parte de tu proyecto que acepte cadenas, lo que reduce la repetición en tu código de LookML.

Las constantes deben declararse dentro de un archivo de manifiesto del proyecto, y su valor debe ser una cadena. Por ejemplo, puedes definir una constante city con el valor "Okayama" de la siguiente manera:

constant: city {
  value: "Okayama"
}

Luego, se puede hacer referencia a la constante city en todo el proyecto con la sintaxis @{city}. Por ejemplo, puedes usar la constante city con el parámetro label en la exploración de users:


explore: users {
  label: "@{city} Users"
}

Luego, Looker muestra Okama Users tanto en el menú Explorar como en el título de Explorar, en lugar de mostrar la opción Usuarios predeterminada.

Para obtener más información y ejemplos de cómo usar las constantes de LookML para escribir código reutilizable, consulta la página de documentación del parámetro constant.