02 · Dialecto SQL¶
Cuaderno asociado
cuadernos/01_sql.ipynb. Volver al 00 - Índice de la demo.
DuckDB no es «SQL de juguete»: su dialecto es uno de los más potentes para el análisis de datos
Mapa de características¶
flowchart TB
SQL["Dialecto DuckDB 2.0"]
SQL --> Q["Consultas"]
SQL --> T["Tipos"]
SQL --> M["Modificación"]
SQL --> PR["Productividad"]
Q --> Q1["FROM-first"]
Q --> Q2["QUALIFY"]
Q --> Q3["ASOF JOIN"]
Q --> Q4["PIVOT / UNPIVOT"]
Q --> Q5["GROUP BY ALL"]
Q --> Q6["NEAREST ... BY SIMILARITY"]
T --> T1["STRUCT, LIST, MAP"]
T --> T2["VARIANT"]
T --> T3["DECIMAL e INTERVAL"]
M --> M1["DML dentro de CTE"]
M --> M2["CTE recursivas + USING KEY"]
M --> M3["COPY / INSERT por lotes"]
PR --> P1["COLUMNS(*) y * EXCLUDE"]
PR --> P2["SUMMARIZE / DESCRIBE"]
PR --> P3["Lambdas: lambda x, i: ..."]
1. FROM¶
El origen de datos puede ir delante; el SELECT es opcional si no hey proyección:
Sirve para explorar rápido y para encadenar pipelines. Cambia cómo se lee una consulta: primero el dato, luego la pregunta.
2. QUALIFY: filtrar sobre ventanas sin subconsultas¶
SELECT cliente_id, pedido_id, importe,
row_number() OVER (PARTITION BY cliente_id ORDER BY importe DESC) AS rn
FROM pedidos
QUALIFY rn <= 3; -- top-3 por cliente, sin CTE
3. AsOf JOIN: alineación de series temporales¶
AsOf Join
What Is an AsOf Join?
Time series data is not always perfectly aligned. Clocks may be slightly off, or there may be a delay between cause and effect. This can make connecting two sets of ordered data challenging. AsOf joins are a tool for solving this and other similar problems.
One of the problems that AsOf joins are used to solve is finding the value of a varying property at a specific point in time. This use case is so common that it is where the name came from:
Give me the value of the property as of this time.
More generally, however, AsOf joins embody some common temporal analytic semantics, which can be cumbersome and slow to implement in standard SQL.
El operador ASOF JOIN (As-Of Join) aporta la capacidad nativa de realizar coincidencias temporales inexactas o difusas (fuzzy temporal lookups), permitiendo obtener el valor o estado más reciente ("a la fecha/hora de...") sin necesidad de que las marcas de tiempo entre ambas tablas coincidan de forma exacta.
Ejemplo clásico: precios de mercado con timestamps irregulares y operaciones entre ellos.
SELECT o.ts, o.activo, p.precio
FROM operaciones o
ASOF JOIN precios p
ON o.activo = p.activo AND o.ts >= p.ts;
4. PIVOT / UNPIVOT volteado en una línea¶
5. GROUP BY ALL¶
Deja que el motor agrupe por todo lo no agregado. Menos ruido, menos errores al añadir una columna:
6. Lambda: Sintaxis nueva en 2.0¶
-- ❌ Desactivado por defecto en 2.0
SELECT list_transform([1, 2, 3], x -> x * 10);
-- ✅ Sintaxis nueva
SELECT list_transform([1, 2, 3], lambda x: x * 10);
SELECT list_transform([10, 20], lambda x, i: x + i); -- con índice
SELECT list_reduce([1, 2, 3], lambda a, b: a + b); -- reducción
Error que aparece al usar la sintaxis anterior
Binder Error: Deprecated lambda arrow (->) detected. Please transition to the new lambda syntax. Si tu código de la 1.x usaba x -> ..., hay que reescribirlo.
7. DML dentro de CTE (Nuevo en 2.0)¶
Insertar y consultar en la misma expresión de tabla:
WITH nuevos AS (
INSERT INTO auditoria (evento, ts)
VALUES ('carga_diaria', now())
RETURNING *
)
SELECT * FROM nuevos;
Útil para pipelines que necesitan trazabilidad sin un segundo viaje a la base de datos.
8. Tipos que evitan el JSON "de pobres"¶
SELECT
{'nombre': 'ana', 'edad': 31} AS persona, -- STRUCT
[1, 2, 3] AS lista, -- LIST
MAP {'es': 'hola', 'en': 'hi'} AS saludo, -- MAP
CAST(12.5 AS DECIMAL(10,2)) AS dinero;
Acceso por punto y por índice: persona.nombre, lista[1] (¡1-indexado!), saludo['es'].
9. Productividad en análisis exploratorio¶
SUMMARIZE SELECT * FROM ventas; -- perfilado por columna: min, max, cuantiles, nulos
DESCRIBE SELECT * FROM ventas; -- tipos inferidos
SELECT COLUMNS('importe.*') FROM ventas; -- regex sobre nombres
SELECT * EXCLUDE (interno) FROM ventas;
SUMMARIZE es la primera consulta que deberías lanzar sobre cualquier tabla nueva.
10. NEAREST ... BY SIMILARITY¶
Búsqueda top-k por similitud como si fuera un JOIN — pensado para vectores y embeddings:
Alcance del taller
Montar embeddings reales exige la extensión vss y un modelo. Este taller únicamente presenta la funcionalidad.
Ejercicios propuestos¶
- Top-2 de productos por facturación en cada categoría usando
QUALIFY, sin subconsultas. - Convertir
SELECT categoria, sum(importe) FROM v GROUP BY categoriaa la formaFROM-primero y añadeORDER BY ALL - Reescribe estas lambdas de la 1.5 a la sintaxis 2.0:
list_filter([1,2,3,4], x -> x % 2 = 0)list_transform(['a','bb'], (x, i) -> i || ':' || x)
- ¿Por qué
SUMMARIZEes mejor primer paso queDESCRIBE?
Soluciones en cuadernos/99_soluciones.ipynb.