Conceptos de SQL para las uniones

Al igual que en SQL, una unión en LookML se usa para combinar filas de dos o más tablas, según una columna relacionada entre ellas.

En LookML, se usa una Exploración (como se define en el parámetro explore de LookML) para definir cómo un usuario puede consultar los datos. Una exploración consta de al menos una vista o un conjunto de vistas unidas. La vista principal de Explorar siempre se incluye en la consulta. Por lo general, las vistas unidas solo se incluyen si son necesarias para satisfacer la consulta.

Una vista de LookML corresponde a una tabla SQL (o a otro elemento que tiene la estructura de una tabla) en la base de datos o a una tabla derivada. La vista define qué campos o columnas están disponibles en la base de datos y cómo se debe acceder a ellos.

El siguiente ejemplo es una definición para la función Explorar de orders.

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

La vista orders, que es la vista principal de Explorar, se unirá a la vista users con un SQL LEFT OUTER JOIN, como lo indica el parámetro type: left_outer de LookML. La cláusula SQL ON, que se define por el parámetro sql_on de LookML, no usa table_alias.column, sino que hace referencia a to ${view_name.field_name}. Esto se hace para que, si cambia el nombre de la tabla o de la columna en la base de datos, ese cambio solo se tenga que realizar en un lugar.

El parámetro relationship es importante. Las uniones pueden causar problemas de fanout en los que se duplican las filas. Cuando se especifica que muchos pedidos se unirán a un solo usuario, Looker reconoce que no se producirán fanouts de esta unión, por lo que no se necesita un manejo especial. Sin embargo, las relaciones one_to_many pueden activar un fanout.

La generación automática de vistas y Exploraciones usa de forma predeterminada una combinación externa izquierda. Sin embargo, en el ejemplo anterior, es muy probable que cada pedido tenga exactamente un usuario, por lo que la unión de este ejemplo puede ser interna.

Para ver el SQL generado de una exploración, puedes ejecutar la exploración en la IU y, luego, seleccionar la pestaña SQL en el panel Datos.

Por ejemplo, si abres la exploración de Pedidos, que se definió anteriormente, y luego seleccionas los campos ID de usuario y Recuento, el SQL generado se verá de la siguiente manera:

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

En este ejemplo, no se hace referencia a la tabla users. Solo se ingresa si es necesario.

Si quitas la dimensión ID del usuario y la agregas ID desde la vista Usuarios, el SQL se verá de la siguiente manera:

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

En este caso, como hay una selección de la vista Usuarios, se incluye la unión.

En el siguiente ejemplo, se muestra LookML en el archivo de exploración orders, que se definió anteriormente, y se agrega una unión a la vista order_items:

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

Ahora, si abres el panel de navegación Pedidos de la IU, verás la vista Pedir artículos. Si seleccionas la medida Total Sale Price desde la vista Order Items junto con el Count de Orders y el ID de Users, Looker genera el siguiente SQL:

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

En este ejemplo, COUNT(*) AS orders.count se convirtió en COUNT(DISTINCT orders.id ) AS orders.count. Looker detectó que había una posible situación de distribución y agregó automáticamente la palabra clave SQL DISTINCT a la función SQL COUNT.