This page refers to the
sql
parameter that is part of a field.
sql
can also be used as part of a derived table, as described on thesql
(for derived tables) parameter documentation page.
Usage
view: view_name { dimension: field_name { sql: ${revenue_in_dollars} - ${inventory_item.cost_in_dollars} ;; } }
Hierarchy
sql |
Possible Field Types
Dimension, Dimension Group, Filter, Measure
Accepts
A SQL expression
Special Rules
A SQL expression that varies according to the type of the field (see below for more details)
|
Definition
The sql
parameter takes several types of SQL expressions that will define a dimension, measure, or filter. The expression you need to write varies based on the type of field you are creating. More details about dimension and filter types can be found on the Dimension, filter, and parameter types documentation page, while more details about measure types can be found on the Measure types documentation page. See also the Incorporating SQL and referring to LookML objects documentation page.
sql
for Dimensions
The sql
block for dimensions can generally take any valid SQL that would go into a single column of a SELECT
statement. These statements generally rely on Looker's substitution operator, which has several forms:
${TABLE}.column_name
references a column in the table that is connected to the view you're working on.${dimension_name}
references a dimension within the view you're working on.${view_name.dimension_name}
references a dimension from another view.${view_name.SQL_TABLE_NAME}
references another view or derived table. (Note thatSQL_TABLE_NAME
in this reference is a literal string; you do not need to replace it with anything.)
If sql
is left unspecified, then Looker assumes that there is a column in the underlying table with the same name as the field. For example, selecting a field called city
without a sql
parameter would be equivalent to specifying sql: ${TABLE}.city
.
The
sql
parameter of a dimension cannot include any aggregations. This means it cannot contain SQL aggregations or references to LookML measures. If you want to create a field withsql
that includes a SQL aggregation or that references a LookML measure, use asql
parameter in a measure, not in a dimension.
A very simple dimension that takes the value directly from a column called revenue
could look like:
dimension: revenue_in_cents {
sql: ${TABLE}.revenue ;;
type: number
}
A dimension that relies on another dimension in the same view could look like this:
dimension: revenue_in_dollars {
sql: ${revenue_in_cents} / 100 ;;
type: number
}
A dimension that relies on another dimension in a different view could look like this:
dimension: profit_in_dollars {
sql: ${revenue_in_dollars} - ${inventory_item.cost_in_dollars} ;;
type: number
}
A dimension that relies on another dimension in a derived table could look like this:
dimension: average_margin {
sql: (SELECT avg(${gross_margin} FROM ${order_facts.SQL_TABLE_NAME})) ;;
type: number
}
More advanced SQL users can perform relatively advanced calculations, including correlated sub-queries (note: not all database dialect support correlated subqueries):
dimension: user_order_sequence_number {
type: number
sql:
(
SELECT COUNT(*)
FROM orders AS o
WHERE o.id <= ${TABLE}.id
AND o.user_id = ${TABLE}.user_id
) ;;
}
For further details, refer to the documentation for a specific dimension type.
sql
for Dimension Groups
The sql
parameter for a dimension_group
takes any valid SQL expression that contains data in a timestamp, datetime, date, epoch, or yyyymmdd format.
sql
for Measures
The sql
block for measures typically takes one of two forms:
- The SQL over which an aggregate function (such as
COUNT
,SUM
,AVG
) will be performed, again using Looker's substitution operator as described in the SQL for Dimensions section - A value based on several other measures
For example, to calculate the total revenue in dollars, we might use:
measure: total_revenue_in_dollars {
sql: ${revenue_in_dollars} ;;
type: sum
}
To calculate our total profit, we might use:
measure: total_revenue_in_dollars {
sql: ${total_revenue_in_dollars} - ${inventory_item.total_cost_in_dollars} ;;
type: number
}
For further details, see the documentation for a specific measure type.
For a count
measure type, you can leave off the sql
parameter.
For other types of measures, if sql
is left unspecified then Looker assumes that there is a column in the underlying table with the same name as the field. Since a measure should have a name indicating that it is an aggregate of an underlying set of values, in practice you should always include a sql
parameter.
SQL math challenges
There are two frequent challenges that come up with division in the sql
parameter.
First, if you are using division in your calculation, you want to protect against the possibility of dividing by zero, which will cause a SQL error. To do so, use the SQL NULLIF
function. For example, this example means "if the denominator is zero, treat it like NULL instead":
measure: active_users_percent {
sql: ${active_users} / NULLIF(${users}, 0) ;;
type: number
}
Another issue is the way that SQL handles integer math. If you divide 5 by 2, most people expect the result to be 2.5. However, many SQL dialects will return the result as just 2, because when it divides two integers it also gives the result as an integer. To address this, you can multiply the numerator by a decimal number to force SQL into returning a decimal result. For example:
measure: active_users_percent {
sql: 100.00 * ${active_users} / NULLIF(${users}, 0) ;;
type: number
}
Liquid variables with sql
You can also use Liquid variables with the sql
parameter. Liquid variables let you access data such as the values in a field, data about the field, and filters applied to the field.
For example, this dimension masks a customer password according to a Looker user attribute:
dimension: customer_password {
sql:
{% if _user_attributes['pw_access'] == 'yes' %}
${password}
{% else %}
"Password Hidden"
{% endif %} ;;
}