Puedes usar filtros basados en plantillas para hacer referencia a fechas seleccionando las fechas de inicio y finalización en un filtro de fecha: {% date_start date_filter %} y {% date_end date_filter %}, respectivamente. En esta página, se explican algunos ejemplos de casos de uso y los pasos para llevarlos a cabo.
Notas de sintaxis
La siguiente sintaxis funciona con la mayoría de los dialectos, pero algunos tienen casos de uso específicos. Ejemplo:-
BigQuery permite un mayor control cuando se trabaja con funciones comodín de tablas, como
TABLE_DATE_RANGEyTABLE_QUERY, por lo que usar{% table_date_range prefix date_filter %}no es suficiente para especificar filtros de fecha. -
Hadoop permite trabajar con columnas particionadas por fecha, independientemente del tipo (
string,date) o el formato (YYYY-MM-DD) de la columna.
Notas de uso
-
Cuando no se especifica ningún valor para
date_filter, tanto{% date_start date_filter %}como{% date_end date_filter %}se evaluarán comoNULL. -
En el caso de un
date_filterabierto (comobefore 2016-01-01oafter 2016-01-01), uno de los filtros{% date_start date_filter %}o{% date_end date_filter %}seráNULL.
Para asegurarte de que ninguno de estos dos casos genere código SQL no válido, puedes usar IFNULL o COALESCE en LookML.
Ejemplos de casos de uso
Columnas particionadas mensualmente (en BigQuery)
En algunos conjuntos de datos de BigQuery, las tablas se organizan por mes, y el ID de la tabla tiene la combinación de año y mes como sufijo. Un ejemplo de esto se encuentra en el siguiente conjunto de datos, que tiene muchas tablas con nombres como pagecounts_201601, pagecounts_201602 y pagecounts_201603.
Ejemplo 1: LookML que depende de always_filter
La siguiente tabla derivada usa TABLE_QUERY([dataset], [expr]) para obtener el conjunto correcto de tablas para consultar:
view: pagecounts {
derived_table: {
sql: SELECT * FROM
TABLE_QUERY([fh-bigquery:wikipedia],
"length(table_id) = 17 AND
table_id >= CONCAT( 'pagecounts_' , STRFTIME_UTC_USEC({% date_start date_filter %},'%Y%m') ) AND
table_id <= CONCAT('pagecounts_' , STRFTIME_UTC_USEC({% date_end date_filter %},'%Y%m') )";
)
;;
}
filter: date_filter {
type: date
}
}
Algunas notas sobre el código de la expresión:
-
table_idhace referencia al nombre de la tabla en el conjunto de datos. -
length(table_id) = 17garantiza que se ignoren las otras tablas con nombres comopagecounts_201407_en_top64k. -
STRFTIME_UTC_USEC({% date_start date_filter %},'%Y%m')solo mostrará la parteYYYYmmde la fecha de inicio.
NULL se sustituirá por las partes de date_filter. Para evitar esto, se requiere un always_filter en la Exploración:
explore: pagecounts {
always_filter: {
filters: [date_filter: "2 months ago"]
}
}
Ten en cuenta que esto seguirá fallando para los filtros de fechas anteriores a la fecha más antigua del conjunto de datos, ya que {% date_start date_filter %} se evaluará como NULL.
Ejemplo 2: LookML que no depende de always_filter
También es posible usar COALESCE o IFNULL para codificar un conjunto predeterminado de tablas para consultar. En el siguiente ejemplo, se usan los últimos dos meses:
-
El límite inferior:
COALESCE({% date_start date_filter %},DATE_ADD(CURRENT_TIMESTAMP(),-2,'MONTH')) -
El límite superior:
COALESCE({% date_end date_filter %},CURRENT_TIMESTAMP())
view: pagecounts {
derived_table: {
sql: SELECT * FROM
TABLE_QUERY([fh-bigquery:wikipedia],
"length(table_id) = 17 AND
table_id >= CONCAT( 'pagecounts_'; , STRFTIME_UTC_USEC(COALESCE({% date_start date_filter %},DATE_ADD(CURRENT_TIMESTAMP(),-2,'MONTH')),'%Y%m') ) AND
table_id <= CONCAT( 'pagecounts_' , STRFTIME_UTC_USEC(COALESCE({% date_end date_filter %},CURRENT_TIMESTAMP()),'%Y%m') )"
)
;;
}
filter: date_filter {
type: date
}
}
Los archivos de registro están en UTC cuando se realizan consultas en zonas horarias de América (en BigQuery)
A veces, tus archivos de registro de Looker se almacenan en UTC, aunque realices consultas en las zonas horarias del este o del Pacífico. Este problema puede provocar que los archivos de registro ya se hayan cambiado a la fecha de mañana
en la zona horaria local de la búsqueda, lo que genera la pérdida de algunos datos.
La solución es agregar un día adicional a la fecha de finalización del filtro de fechas para asegurarte de que, si ya pasó la medianoche UTC, se seleccionen esas entradas de registro.
En los siguientes ejemplos, se usa el conjunto de datos públicos [githubarchive:day], que tiene una partición diaria de la información de GitHub.
Ejemplo 1: LookML que depende de always_filter
view: githubarchive {
derived_table: {
sql: SELECT * FROM
TABLE_DATE_RANGE([githubarchive:day.],
{% date_start date_filter %},
DATE_ADD({% date_end date_filter %},1,"DAY")
)
;;
}
filter: date_filter {
type: date
}
}
Dado que este código SQL fallará si se sustituye NULL por las fechas, es necesario agregar un always_filter a la Exploración:
explore: githubarchive {
always_filter: {
filters: [date_filter: "2 days ago"]
}
}
Ejemplo 2: LookML que no depende de always_filter
En este ejemplo, el período predeterminado está codificado en LookML. Como COALESCE devolvía un tipo unknown, en última instancia, tuve que usar IFNULL para que funcionara el código SQL.
-
El límite inferior:
IFNULL({% date_start date_filter %},CURRENT_DATE()) -
Límite superior:
IFNULL({% date_end date_filter %},CURRENT_DATE())+ 1 día
view: githubarchive {
derived_table: {
sql: SELECT * FROM
TABLE_DATE_RANGE([githubarchive:day.],
IFNULL({% date_start date_filter %},CURRENT_TIMESTAMP()),
DATE_ADD(IFNULL({% date_end date_filter %},CURRENT_TIMESTAMP()),1,"DAY")
)
;;
}
filter: date_filter {
type: date
}
}
Funciones de ventana rezagada de N días (en BigQuery)
Cuando realices ciertos análisis, es posible que desees agregar datos durante un período histórico. Para realizar esta operación en SQL, por lo general, se implementa una función de ventana que alcanza una cantidad de filas n para una tabla única por fecha. Sin embargo, hay una situación paradójica cuando se usa una tabla particionada por fecha: primero se debe indicar el conjunto de tablas con las que se ejecutará la consulta, incluso cuando la consulta realmente necesita tablas históricas adicionales para el cálculo.
Solución: Permite que la fecha de inicio sea anterior a las fechas proporcionadas en el filtro de fecha. A continuación, se muestra un ejemplo que se remonta a una semana adicional:
view: githubarchive {
derived_table: {
sql: SELECT y._date,
y.foo,
y.bar
FROM (
SELECT _date,
SUM(foo) OVER (ORDER BY _date RANGE BETWEEN x PRECEDING AND CURRENT ROW),
COUNT(DISTINCT(bar)) OVER (ORDER BY _date RANGE BETWEEN x PRECEDING AND CURRENT ROW)
FROM (
SELECT _date,
foo,
bar
FROM TABLE_DATE_RANGE([something:something_else.], DATE_ADD(IFNULL({% date_start date_filter %},CURRENT_TIMESTAMP()), -7, "DAY"), IFNULL({% date_end date_filter %},CURRENT_TIMESTAMP()))
) x
) y
WHERE {% condition date_filter %} y._date {% endcondition %};;
}
filter: date_filter {
type: date
}
}
La instrucción SELECT adicional es necesaria porque proporciona una restricción WHERE para reducir el conjunto de resultados al período que el usuario especificó originalmente en la búsqueda.
Tabla particionada por fecha a través de una cadena con el formato "AAAA-MM-DD" (en Presto)
En las tablas de Hadoop, es común usar columnas particionadas para acelerar los tiempos de búsqueda de las columnas que se buscan con frecuencia, en especial las fechas. El formato de las columnas de fecha puede ser arbitrario, aunque YYYY-MM-DD y YYYYMMDD son los más comunes. El tipo de columna de fecha puede ser cadena, fecha o número.
En este ejemplo, una tabla de Hive table_part_by_yyyy_mm_dd tiene una columna particionada dt, una cadena con formato YYYY-MM-DD, que Presto está buscando.
Cuando se ejecuta el generador por primera vez, el LookML se ve de la siguiente manera:
view: table_part_by_yyyy_mm_dd {
sql_table_name: hive.taxi. table_part_by_yyyy_mm_dd ;;
suggestions: no
dimension: dt {
type: string
sql: ${TABLE}.dt ;;
}
}
A continuación, se incluyen algunas notas sobre el código de las expresiones en ambos ejemplos:
-
El resultado de
date_startydate_endestype: timestamp. -
date_format( <expr>, '%Y-%m-%d')se usa para convertir la marca de tiempo en una cadena y en el formato correcto. -
El
coalescese usa para controlar el caso de los valores NULL si alguien escribe un filtro comobefore 2010-01-01oafter 2012-12-31. -
Este es código de dialecto de Presto, por lo que Hive tendrá algunas diferencias en la cadena de formato (
yyyy-MM-dd), ydate_formatno puede tomar un valor NULL, por lo quecoalescetendría que moverse allí con algún tipo de valor predeterminado.
Ejemplo 1: LookML que usa una expresión de tabla común para filtrar la tabla
En este ejemplo, se usa una tabla derivada para filtrar la tabla.
view: table_part_by_yyyy_mm_dd {
# sql_table_name: hive.taxi. table_part_by_yyyy_mm_dd
suggestions: no
derived_table: {
sql: SELECT * FROM hive.taxi. table_part_by_yyyy_mm_dd
WHERE ( coalesce( dt >= date_format({% date_start date_filter %}, '%Y-%m-%d'), TRUE) )
AND ( coalesce( dt <= date_format({% date_end date_filter %}, '%Y-%m-%d'), TRUE) )
;;
}
filter: date_filter {
type: date
}
dimension: dt {
type: string
sql: ${TABLE}.dt ;;
}
}
Por lo general, las tablas particionadas tardan demasiado en realizar análisis de tablas completos (y consumen demasiados recursos del clúster), por lo que es una buena idea colocar un filtro predeterminado en el Explorador para esta vista también:
explore: table_part_by_yyyy_mm_dd {
always_filter: {
filters: [date_filter: "2013-01"]
}
}
Ejemplo 2: LookML que filtra directamente en el predicado
En este ejemplo, el filtrado de predicados se realiza directamente en la tabla, sin una subconsulta ni una expresión de tabla común.
view: table_part_by_yyyy_mm_dd {
sql_table_name: hive.taxi.table_part_by_yyyy_mm_dd ;;
filter: date_filter {
type: date
sql: ( coalesce( ${dt} >= date_format({% date_start date_filter %}, '%Y-%m-%d'), TRUE) )
AND ( coalesce( ${dt} <= date_format({% date_end date_filter %}, '%Y-%m-%'), TRUE) );;
}
dimension: dt {
type: string
sql: ${TABLE}.dt ;;
}
}
Para validar que las particiones de la tabla se estén usando, verifica el resultado de EXPLAIN en SQL Runner para una consulta generada por este LookML (puedes acceder a él haciendo clic en la sección SQL de la pestaña Datos de la página Explorar). Verás algo como lo siguiente:
output[table_part_by_yyyy_mm_dd.count] => [count:bigint]
table_part_by_yyyy_mm_dd.count := count
TopN[500 by (count DESC_NULLS_LAST)] => [count:bigint]
Aggregate(FINAL) => [count:bigint]
count := "count"("count_4")
RemoteExchange[GATHER] => count_4:bigint
Aggregate(PARTIAL) => [count_4:bigint]
count_4 := "count"(*)
Filter[(COALESCE(("dt" >= CAST('2013-04-01' AS VARCHAR)), true) AND COALESCE(("dt" <= CAST('2016-08-01' AS VARCHAR)), true))] => [dt:varchar]
TableScan[hive:hive:taxi: table_part_by_yyyy_mm_dd, originalConstraint = (COALESCE(("dt" >= CAST('2013-04-01' AS VARCHAR)), true) AND COALESCE(("dt" <= CAST('2016-08-01' AS VARCHAR)), true))] => [dt:varchar]
LAYOUT: hive dt := HiveColumnHandle{clientId=hive, name=dt, hiveType=string, hiveColumnIndex=-1, partitionKey=true}
:: [[2013-04-01, 2013-12-31]]
El partitionKey=true junto con el rango de claves de partición que se indican señalan que solo se analizan esas columnas particionadas.