Durante o desenvolvimento num projeto, pode ver um erro como o seguinte numa exploração ou no validador de LookML:
Measures with Looker aggregations (sum, average, min, max, list types) may not reference other measures.
Este erro é causado por uma medida agregada que faz referência a outra agregação ou medida de qualquer tipo na respetiva definição do LookML, como:
SELECT AVG((COUNT(*)) ) AS users.average_count FROM demo_db.users AS users
As declarações SQL, como esta, geram uma agregação dupla ou aninhada em SQL. A maioria dos dialetos SQL não consegue fazer uma agregação dupla nem aninhar agregações, pelo que uma tentativa deste tipo aciona o erro.
Soluções
Existem duas soluções possíveis:
- Use medidas não agregadas para executar declarações SQL não agregadoras entre medidas.
- Use uma tabela derivada para aninhar agregações ou agregar duas vezes.
Usar medidas não agregadas
As medidas não agregadas, como type: yesno e type: number, são as únicas medidas que podem fazer referência a outras medidas ou agregações. As medidas não agregadas não realizam qualquer agregação e, por isso, não realizam uma agregação dupla ou aninhada. As medidas de type: number ou type: yesno atuam como marcadores de posição para que outras medidas ou combinações de medidas possam ser referenciadas nas mesmas.
Por exemplo, as medidas de type: number são usadas para fazer cálculos entre medidas e aceitar qualquer expressão SQL válida que resulte num número ou num inteiro.
O exemplo seguinte usa um type: number para calcular a percentagem de todas as encomendas que são canceladas:
measure: order_count { # Base measure #1
type: count
sql: ${order_id} ;;
}
measure: cancelled_orders { # Base measure #2
type: count
filters: [status: "Cancelled"]
}
measure: percent_cancelled_orders { # New measure
type: number
sql: (1.0*${cancelled_orders})/ISNULL(${order_count},0) ;;
}
Usar uma tabela derivada para agregações duplas ou aninhadas
Mas e se for necessária uma agregação aninhada para realizar uma análise? Por exemplo, e se precisar de saber o valor médio que os clientes gastam durante o seu ciclo de vida ("valor do cliente médio")? Isto requer dois níveis, ou seja, uma duplicação ou aninhamento, de agregações, incluindo:
-
Uma soma das vendas, agrupadas por cliente
-
Uma média dessa soma
Para alcançar este objetivo com o LookML, pode experimentar:
measure: total_revenue {
type: sum
sql: ${sale_price} ;;
}
measure: avg_customer_lifetime_value {
type: average
sql: ${total_revenue} ;;
}
No entanto, isto aciona o erro porque a medida avg_customer_lifetime_value está a fazer uma agregação na medida total_revenue, que já é uma agregação. Conforme abordado anteriormente, a maioria dos dialetos SQL aciona um erro quando são usados agregados duplos ou aninhados numa consulta.
Para alcançar uma média da soma no SQL, é necessária uma subconsulta, como a seguinte:total_revenue
SELECT AVG(s.sum) FROM (SELECT SUM(x) as sum FROM ...) AS s
A solução equivalente no Looker é criar uma tabela derivada para "aplanar" a medida total_lifetime_value num campo que possa ser agregado. No Looker, isto chama-se tornar uma medida dimensional. Com uma tabela derivada, a medida total_lifetime_value torna-se uma dimensão. Em seguida, pode criar uma medida de type: average que faça referência à dimensão customer_lifetime_value:
view: customer_facts {
derived_table: {
sql:
SELECT
user_id,
COALESCE(SUM(sale_price), 0) AS customer_lifetime_value
FROM orders
GROUP BY user_id;;
}
dimension: customer_lifetime_value {
type: number
sql: ${TABLE}."customer_lifetime_value" ;;
}
measure: average_customer_lifetime_value {
type: average
sql: ${customer_lifetime_value} ;;
}
}
Depois de a tabela derivada customer_facts ser associada a um elemento Explorar, a medida average_customer_lifetime_value pode ser usada para realizar a análise pretendida num elemento Explorar sem acionar nenhum erro.