Integración de datos

Integración Google Sheets con DuckDB: SQL en vivo

Marc Sean17 de abril de 20269 min de lectura

Google Sheets llega bastante lejos con fórmulas - hasta que alguien pide un JOIN entre tres hojas, o un promedio móvil particionado por región y trimestre. En ese momento, SUMIFS empieza a verse como la herramienta equivocada. Una integración con DuckDB cambia la ecuación: obtienes un motor SQL completo operando directamente sobre los datos de tu hoja, sin exportar nada.

Ese es el argumento de venta. La realidad es más matizada, y vale la pena entenderla antes de configurarlo.

Qué agrega DuckDB a Google Sheets

Google Sheets tiene QUERY(), que habla un dialecto SQL bastante limitado. Maneja SELECT y WHERE básicos, pero tropieza con cualquier cosa que implique múltiples rangos como fuente, agregaciones sobre JOINs o window functions. DuckDB no tiene esas restricciones: es un motor OLAP completo que soporta SQL estándar, incluyendo CTEs, lateral joins y QUALIFY para filtrar resultados de window functions.

La diferencia arquitectónica importa. QUERY() se evalúa dentro del motor de fórmulas de Sheets, lo que significa que está limitado a lo que ese motor expone. DuckDB corre como una base de datos en proceso separado que lee los datos de tu hoja como input tabular. Tu hoja de cálculo se convierte en una fuente de datos, no en el entorno de ejecución.

FuncionalidadQUERY() nativoDuckDB
SELECT / WHERE básico✓✓
JOINs entre múltiples rangos✗✓
Window functions (OVER, PARTITION BY)✗✓
CTEs (WITH …)✗✓
HAVING sobre agregacionesParcial✓
QUALIFY para filtrar window functions✗✓
Múltiples hojas como fuenteNoSí
Velocidad con rangos de +10.000 filasLentaRápida (motor columnar)

En la práctica, esto habilita:

  • Unir dos rangos de hojas distintas sobre una columna clave común
  • Calcular promedios móviles o acumulados con OVER (PARTITION BY … ORDER BY …)
  • Filtrar resultados agregados con HAVING en lugar de envolver todo en una subconsulta
  • Ejecutar GROUP BY sobre múltiples dimensiones simultáneamente

Cómo configurar la integración de DuckDB en Google Sheets

Hay varias formas de hacer que DuckDB opere sobre datos de Sheets - Cómo conectar DuckDB a Google Sheets las cubre en detalle. La versión corta: o exportas los datos a un formato que DuckDB pueda leer (CSV, Parquet), o usas una capa de integración que maneja el puente de datos automáticamente.

El enfoque más robusto es embeber DuckDB directamente en el flujo de trabajo, de modo que el motor de consultas tenga acceso en vivo a los rangos de la hoja en lugar de a exportaciones desactualizadas. ModelMonkey lo implementa registrando una función de tabla sheet_range() como UDF de DuckDB, lo que permite referenciar rangos en notación A1 directamente dentro de las consultas SQL:

SELECT
  categoria,
  SUM(ingresos)   AS ingresos_totales,
  AVG(margen_pct) AS margen_promedio
FROM sheet_range('P&L!B2:E500')
GROUP BY categoria
ORDER BY ingresos_totales DESC

La consulta corre contra los datos actuales de la hoja en el momento de ejecución. Sin paso de exportación, sin CSV desactualizado. Los tipos de columna se infieren automáticamente: los números llegan como DOUBLE, los booleanos como BOOLEAN, y los campos mixtos quedan como VARCHAR por defecto. Según la documentación de DuckDB 1.0 - versión vigente a abril de 2026 - la inferencia de tipos maneja bien la mayoría de los datos financieros, aunque ocasionalmente necesitarás casts explícitos cuando una columna mezcla encabezados de texto con valores numéricos.

Caso de uso: P&L consolidado con varianza YoY

El escenario más frecuente en equipos de FP&A no es el análisis ad hoc - es la consolidación de estados financieros distribuidos en pestañas separadas. Considera una empresa mediana con tres hojas: resultados del año en curso, resultados del año anterior y una tabla de ajustes por partidas no recurrentes. Construir el Estado de Resultados consolidado con varianza YoY normalmente implica una cadena de VLOOKUPs entre pestañas, columnas auxiliares de diferencia y una tabla dinámica que alguien tiene que actualizar manualmente cada cierre de mes.

Con DuckDB, todo eso colapsa en una sola consulta:

WITH actual_2025 AS (
  SELECT linea, SUM(monto) AS monto_2025
  FROM sheet_range('ER_2025!A2:C200')
  GROUP BY linea
),
actual_2024 AS (
  SELECT linea, SUM(monto) AS monto_2024
  FROM sheet_range('ER_2024!A2:C200')
  GROUP BY linea
),
ajustes AS (
  SELECT linea, SUM(monto_ajuste) AS ajuste_no_recurrente
  FROM sheet_range('Ajustes!A2:B50')
  GROUP BY linea
)
SELECT
  a25.linea,
  a25.monto_2025                                              AS monto_2025,
  COALESCE(a24.monto_2024, 0)                                AS monto_2024,
  COALESCE(aj.ajuste_no_recurrente, 0)                       AS ajuste,
  a25.monto_2025 - COALESCE(aj.ajuste_no_recurrente, 0)      AS monto_normalizado,
  ROUND(
    100.0 * (a25.monto_2025 - COALESCE(a24.monto_2024, 0))
    / NULLIF(ABS(COALESCE(a24.monto_2024, 0)), 0),
    1
  )                                                           AS varianza_yoy_pct
FROM actual_2025 a25
LEFT JOIN actual_2024 a24 ON a25.linea = a24.linea
LEFT JOIN ajustes aj      ON a25.linea = aj.linea
ORDER BY a25.linea

El output es un P&L consolidado con columna de ajuste por partidas no recurrentes, monto normalizado y varianza YoY porcentual - exactamente lo que un CFO necesita ver antes de un board meeting o una reunión con inversionistas. Cada vez que alguien actualiza los datos de origen en cualquiera de las tres hojas, la consulta refleja el cambio en la siguiente ejecución.

¿Es esto auditable?

La objeción más común al enfoque SQL es que "oculta la derivación". La realidad es la inversa: una cadena de VLOOKUPs entre 12 pestañas con columnas auxiliares intermedias es opaca por definición - la lógica está enterrada en funciones anidadas que hay que rastrear celda por celda. Una consulta SQL documenta explícitamente cada condición de JOIN, cada cálculo y cada fuente de datos en un texto legible de corrido. Quien no conoce el modelo puede leer la consulta anterior y entender exactamente cómo se calculó la varianza YoY. Eso es trazabilidad, no ocultamiento.

Para equipos que necesitan auditoría celda por celda - informes regulatorios, auditorías externas - el enfoque correcto es usar las consultas SQL para la fase de análisis y exploración, y mantener los libros formales en el formato que los auditores esperan. Ambos usos pueden coexistir sin problema.

Los límites que realmente importan

La documentación de la API de Google Sheets v4 establece un límite duro de 10 millones de celdas por hoja de cálculo. DuckDB puede manejar datasets órdenes de magnitud más grandes - pero dentro de una integración con Sheets, estás acotado por lo que Sheets puede contener. Para empresas medianas de la región (ingresos de $2-50M USD, equipos de 50-500 personas), ese límite rara vez es el cuello de botella.

Lo que sí importa es el tamaño del resultado. Retornar 50.000 filas inline a una hoja de cálculo es lento e inútil - lo que querías era el agregado, no los registros brutos. Una integración bien diseñada limita los resultados inline a alrededor de 200 filas y dirige los outputs más grandes a una hoja destino. Esto mantiene el entorno de trabajo limpio sin sacrificar el acceso a conjuntos de datos completos.

Los tiempos de consulta son el otro límite práctico. Los JOINs complejos contra rangos grandes pueden tomar varios segundos. La instancia de DuckDB corre en memoria, lo cual es rápido, pero el cuello de botella suele ser la recuperación de datos del rango desde la API de Sheets - ese viaje de ida y vuelta agrega latencia proporcional al tamaño del rango consultado.

Dónde gana el enfoque embebido

El enfoque de exportar y consultar (exportar a CSV, correr DuckDB localmente, reimportar resultados) funciona, pero tiene un problema de fricción: los datos están desactualizados desde el momento en que los exportas. Si estás construyendo análisis que necesita refrescarse a medida que la hoja se actualiza - cierres mensuales, dashboards de ventas, seguimiento de inventario - vuelves a los pasos manuales cada vez.

Una integración embebida donde DuckDB lee los rangos en el momento de la consulta resuelve esto. La consulta siempre refleja el estado actual de la hoja. Para modelos de FP&A que se actualizan durante el mes con cifras reales, esto elimina la sincronización manual entre la fuente y el análisis.

Resumen

DuckDB en Google Sheets agrega capacidad SQL real - JOINs, window functions, CTEs, agregaciones complejas - sobre datos en vivo de la hoja de cálculo. El límite de 10 millones de celdas establecido por la API de Google Sheets v4 define el techo, pero para la mayoría de los equipos empresariales en LATAM ese límite no es el problema. El enfoque embebido (DuckDB leyendo rangos directamente vía una UDF registrada) supera al enfoque de exportación porque los datos siempre están vigentes. Las restricciones prácticas son el tamaño del resultado inline (~200 filas por defecto; outputs más grandes se escriben a una hoja destino) y la latencia de recuperación de datos para rangos muy extensos.

Si tu flujo de trabajo incluye consolidar estados financieros de varias pestañas, calcular varianzas YoY o construir análisis multidimensionales que hoy dependen de docenas de VLOOKUPs encadenados, la integración con DuckDB resuelve exactamente ese problema - con una lógica que cualquiera puede leer y auditar.

Elige un plan de ModelMonkey - disponible tanto en Google Sheets como en Excel.


Preguntas frecuentes

¿Necesito exportar mis datos para usar DuckDB con Google Sheets?

No. El enfoque embebido lee los rangos directamente desde la hoja en el momento de la consulta, usando una función de tabla registrada como UDF de DuckDB. No hay paso de exportación: los datos que procesa DuckDB son siempre los datos actuales de tu hoja, sin archivos intermedios.

¿Cuántas filas puede procesar DuckDB en Google Sheets?

DuckDB como motor no tiene un límite práctico para cargas de trabajo típicas - puede manejar cientos de millones de filas. El límite real lo impone Google Sheets: 10 millones de celdas por hoja de cálculo, según la documentación de la API de Google Sheets v4. Los resultados que se devuelven inline a la hoja se limitan a ~200 filas por defecto; los outputs más grandes se escriben a una hoja destino separada.

¿En qué se diferencia DuckDB de usar QUERY() en Google Sheets?

QUERY() soporta un subconjunto limitado de SQL y solo puede operar sobre un rango a la vez - sin JOINs entre pestañas, sin window functions, sin CTEs. DuckDB es un motor OLAP completo: soporta SQL estándar, puede cruzar múltiples rangos de hojas distintas en una sola consulta y maneja grandes volúmenes de datos con un motor columnar optimizado para análisis. La tabla comparativa al inicio del artículo resume las diferencias funcionales punto por punto.