Conceitos de SQL para junções

Tal como no SQL, uma junção no LookML é usada para combinar linhas de duas ou mais tabelas, com base numa coluna relacionada entre elas.

No LookML, um Explore, conforme definido pelo parâmetro LookML explore, é usado para definir como um utilizador pode consultar os dados. Uma exploração consiste em, pelo menos, uma visualização de propriedade ou um conjunto de visualizações de propriedade unidas. A vista principal da funcionalidade Explorar está sempre incluída na consulta. Normalmente, as vistas unidas só são incluídas se forem necessárias para satisfazer a consulta.

Uma vista do LookML corresponde a uma tabela SQL (ou a outro elemento com a estrutura de uma tabela) na base de dados ou a uma tabela derivada. A vista define que campos ou colunas estão disponíveis na base de dados e como devem ser acedidos.

O exemplo seguinte é uma definição para o elemento orders Explore.

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

A vista orders, que é a vista principal na exploração, está a ser unida à vista users com um SQL LEFT OUTER JOIN, conforme indicado pelo parâmetro LookML type: left_outer. A cláusula SQL ON, que é definida pelo sql_on parâmetro LookML, não usa table_alias.column, mas refere-se a to ${view_name.field_name}. Isto permite que, se o nome da tabela ou o nome da coluna mudar na base de dados, essa alteração só tenha de ser feita num local.

O parâmetro relationship é importante. As junções podem causar problemas de fanout, em que as linhas são duplicadas. Ao especificar que muitas encomendas vão juntar-se a apenas um utilizador, o Looker reconhece que não vão ocorrer fanouts a partir desta junção, pelo que não é necessário um processamento especial. No entanto, as relações one_to_many podem acionar uma distribuição.

A geração automática de visualizações e explorações usa por predefinição uma junção externa esquerda. No exemplo anterior, no entanto, é muito provável que cada encomenda tenha exatamente um utilizador, pelo que a junção neste exemplo pode ser uma junção interna.

Para ver o SQL gerado de um conteúdo de Explorar, pode executar o conteúdo de Explorar na IU e, em seguida, selecionar o separador SQL no painel Dados.

Por exemplo, se abrir a análise detalhada Encomendas, que foi definida anteriormente, e, em seguida, selecionar os campos ID do utilizador e Contagem, o SQL gerado terá o seguinte aspeto:

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

Neste exemplo, a tabela users não é referenciada. Só é usado se for necessário.

Se remover a dimensão ID do utilizador e adicionar a dimensão ID da vista Utilizadores, o SQL terá o seguinte aspeto:

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

Neste caso, uma vez que existe uma seleção na vista Utilizadores, a junção é incluída.

O exemplo seguinte mostra o LookML no ficheiro orders Explore, que foi definido anteriormente, e adiciona uma junção à 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
  }
}

Agora, se abrir a exploração Encomendas na IU, verá a vista Itens de encomenda. Se selecionar a medida Preço total de venda na vista Itens da encomenda juntamente com a Contagem de Encomendas e o ID de Utilizadores, o Looker gera o seguinte 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

Neste exemplo, COUNT(*) AS orders.count tornou-se COUNT(DISTINCT orders.id ) AS orders.count. O Looker detetou uma possível situação de fanout e adicionou automaticamente a palavra-chave SQL DISTINCT à função SQL COUNT.