Análisis de datos

Soporte de la función QUERY en Google Sheets: guía

Marc Sean18 de abril de 20268 min de lectura

La función QUERY de Google Sheets soporta ocho tipos de cláusulas del lenguaje GQL (Google Visualization API Query Language): SELECT, WHERE, GROUP BY, PIVOT, ORDER BY, LIMIT, OFFSET y LABEL. Lo que no soporta - y aquí es donde la mayoría de los analistas se tropieza - son subconsultas, funciones de ventana, JOINs entre rangos distintos y propagación confiable de valores nulos. Esas cuatro limitaciones son las que hacen colapsar la función en modelos financieros reales, y vale la pena entenderlas antes de construir algo que dependa de ellas.

Qué soporta la función QUERY de Google Sheets

El conjunto de cláusulas está documentado en la referencia del lenguaje de consulta de la API de Visualización de Google. A abril de 2026, cubre lo siguiente:

CláusulaQué hace¿Funciona entre pestañas?
SELECTSeleccionar y reordenar columnasSí
WHEREFiltrar filas por condiciónSí
GROUP BYAgregar con SUM, AVG, COUNT, MAX, MINSí
PIVOTCrear tablas de referencias cruzadasSí, con matices
ORDER BYOrdenar de forma ascendente o descendenteSí
LIMITLimitar la cantidad de filasSí
OFFSETSaltar filas inicialesSí
LABELRenombrar columnas en el resultadoSí

Un caso de uso típico en FP&A: extraer todas las transacciones superiores a $50,000 USD de un libro mayor con más de 20,000 filas y agruparlas por centro de costo - sin columnas auxiliares, sin rangos intermedios.

=QUERY('Detalle GL'!A:F,
  "SELECT B, SUM(F)
   WHERE F > 50000
   GROUP BY B
   ORDER BY SUM(F) DESC
   LABEL SUM(F) 'Gasto Total'",
  1)

Las referencias entre pestañas funcionan sin problemas - 'Detalle GL'!A:F es sintaxis estándar. Lo que la función interpreta internamente como columnas (Col1, Col2, etc. o letras de columna según la forma en que la invoques) lo cubrimos en un artículo aparte sobre sintaxis Col1 Col2 en QUERY.

La cláusula PIVOT merece mención especial. Es genuinamente útil para convertir una tabla plana de transacciones en una matriz estilo Estado de Resultados sin necesidad de una tabla dinámica. El detalle: los valores de las columnas pivoteadas deben conocerse al momento de escribir la fórmula, y las columnas del resultado aparecen de forma dinámica - lo que significa que las fórmulas posteriores que referencian columnas por posición se rompen cuando los datos cambian. Para reportes de directorio o board packs, esto tiene consecuencias concretas.

Qué no cubre el soporte de la función QUERY en Google Sheets

Esta es la sección más importante para quienes construyen modelos con múltiples pestañas. La especificación GQL deja claro qué queda excluido:

Subconsultas. No es posible anidar una QUERY dentro de otra. Si necesitas filtrar por un resultado agregado - por ejemplo, solo los centros de costo donde el gasto total supera $1M USD - la solución es en dos pasos: primero ejecutas la QUERY en un rango auxiliar y luego consultas ese rango. Algo engorroso, pero funciona.

Funciones de ventana. No hay ROW_NUMBER(), ni RANK(), ni totales acumulados con OVER PARTITION BY. Para un análisis de margen de contribución ordenado por SKU, tienes que volcar los datos en una columna auxiliar o aceptar que QUERY no puede hacerlo de forma nativa.

JOINs entre rangos distintos. QUERY opera sobre un único rango contiguo. No puedes cruzar 'P&L'!A:D con 'Headcount'!A:C dentro de una misma llamada a QUERY. La solución que usan la mayoría de los analistas es la concatenación de arreglos {rango1, rango2} para fusionar dos rangos antes de consultar - lo que exige que ambos tengan el mismo número de filas y genera referencias de columna frágiles.

Manejo de valores nulos. GQL trata las celdas en blanco como nulos, pero no los propaga de forma consistente a través de todas las agregaciones. SUM ignora los nulos correctamente; AVG también. Sin embargo, la sintaxis WHERE Col3 is null funciona de manera inconsistente según si la celda está genuinamente vacía o contiene una cadena de longitud cero. En la práctica, añade wrappers con IFERROR y prueba con una muestra antes de confiar en filtros de nulos en producción.

Para poner las cosas en perspectiva: una QUERY que condensa 50,000 filas de transacciones en un resumen limpio de 30 filas por centro de costo se ejecuta en menos de 2 segundos en una instancia moderna de Sheets. El rendimiento no es el cuello de botella - estas limitaciones estructurales sí lo son.

Cómo escribir fórmulas QUERY que no se rompan

El modo de falla más frecuente en modelos con 8 pestañas interconectadas son las fórmulas QUERY que referencian posiciones (Col1, Col2) en lugar de letras de columna. Cuando alguien inserta una columna aguas arriba, cada QUERY basada en posiciones se desplaza silenciosamente.

Prefiere las letras de columna cuando consultas un rango con nombre o una referencia a una pestaña cuyo esquema es estable:

=QUERY(INDIRECT("'P&L'!A:H"),
  "SELECT A, C, D
   WHERE C >= " & Supuestos!$B$3 & "
   AND D <> ''
   ORDER BY A",
  1)

Los cortes de fecha dinámicos - como extraer reales hasta el cierre del mes para el reporte de directorio - funcionan concatenando el valor de la celda de referencia en la cadena de consulta. El patrón Supuestos!$B$3 del ejemplo anterior es la forma correcta de hacerlo. No hardcodees fechas dentro de la cadena de consulta.

La cláusula LABEL suele pasarse por alto. Renombra las columnas del resultado sin tocar la fuente de datos, lo que significa que los encabezados de tu reporte quedan limpios aunque los nombres de columna originales sean abreviaciones en código. Úsala:

=QUERY('Ingresos'!A:E,
  "SELECT B, SUM(E)
   WHERE A = 'Q1'
   GROUP BY B
   LABEL B 'Unidad de Negocio', SUM(E) 'Ingresos Q1 (USD)'",
  1)

Para modelos con múltiples pestañas: si consultas datos de distintas hojas con frecuencia, consolida primero la información en una pestaña de staging. Una sola QUERY sobre un rango de 20,000 filas supera en velocidad y capacidad de depuración a seis QUERYs distribuidas en seis pestañas separadas.

Cuándo QUERY deja de ser la herramienta correcta

La limitación de los JOINs es la respuesta honesta a la pregunta "¿cuándo debo dejar de usar QUERY?". Si tu análisis necesita reconciliar dos conjuntos de datos - por ejemplo, cruzar 3,400 facturas de 'Cuentas por Pagar' contra los registros de pago en 'Tesorería' por número de factura - QUERY no puede hacerlo. INDEX/MATCH resuelve búsquedas de uno a uno; SUMIFS resuelve búsquedas con agregación; pero las uniones relacionales requieren una columna auxiliar o algo fuera de la sintaxis nativa de QUERY.

Otra limitación frecuente en la práctica: agregar datos de pestañas con esquemas distintos. QUERY no puede hacer una unión dinámica de rangos como 'Enero'!A:F, 'Febrero'!A:F, 'Marzo'!A:F a menos que los concatenes explícitamente con {'Enero'!A:F; 'Febrero'!A:F; 'Marzo'!A:F} - y eso se vuelve inmanejable a partir de unos pocos meses.

La integración de ModelMonkey con DuckDB resuelve estos casos permitiéndote ejecutar SQL real sobre rangos de hojas, incluyendo JOINs entre pestañas distintas. En la práctica, la sintaxis se ve así:

SELECT cp.invoice_id, cp.amount, t.payment_date
FROM sheet_range('CuentasPorPagar!A:D') cp
JOIN sheet_range('Tesoreria!A:C') t ON cp.invoice_id = t.invoice_id
WHERE cp.amount > 10000

Esa es la salida de emergencia cuando las limitaciones de QUERY empiezan a costarte tiempo real. El artículo sobre integración de DuckDB con Google Sheets explica cómo configurarlo.

Preguntas frecuentes sobre el soporte de la función QUERY en Google Sheets

¿Cuántas cláusulas soporta la función QUERY de Google Sheets?

La función QUERY soporta exactamente ocho cláusulas: SELECT, WHERE, GROUP BY, PIVOT, ORDER BY, LIMIT, OFFSET y LABEL. Todas corresponden al estándar GQL (Google Visualization API Query Language) y funcionan tanto sobre rangos de una sola pestaña como entre pestañas distintas dentro del mismo archivo.

¿Puede QUERY hacer JOINs entre pestañas distintas de Google Sheets?

No. QUERY opera sobre un único rango contiguo; no puede cruzar datos de dos pestañas dentro de la misma llamada a la función. El workaround más común es concatenar los rangos con la sintaxis {rango1, rango2} antes de pasarlos a QUERY, aunque esto exige que ambos tengan el mismo número de filas y produce referencias de columna frágiles. Para JOINs relacionales reales, la alternativa es usar una integración de SQL sobre Sheets como la descrita en el artículo de DuckDB.

¿Cómo maneja QUERY los valores nulos en Google Sheets?

GQL trata las celdas en blanco como nulos, pero su comportamiento no es completamente consistente. Las funciones de agregación SUM y AVG ignoran los nulos sin problema. Sin embargo, los filtros con WHERE Col IS NULL pueden comportarse de forma distinta dependiendo de si la celda está realmente vacía o contiene una cadena de longitud cero (un resultado frecuente al importar datos de sistemas externos). La práctica recomendada es envolver la fórmula en IFERROR y validar el comportamiento con una muestra representativa antes de usar filtros de nulos en reportes de producción.

¿Soporta QUERY subconsultas o funciones de ventana?

No. No es posible anidar una QUERY dentro de otra, y la función no tiene equivalente a ROW_NUMBER(), RANK() ni cálculos de tipo OVER PARTITION BY. Para filtrar por resultados agregados o calcular rankings, la solución estándar es escribir la primera QUERY en un rango auxiliar y luego consultar ese rango en una segunda QUERY.