Aprende SQL · lección gratuita
Una vista (VIEW) es una consulta almacenada con nombre que se comporta como una tabla virtual: no guarda datos propios, sino que ejecuta su SELECT cada vez que la consultas. Sirve para encapsular lógica compleja (joins, agregaciones, filtros) detrás de un nombre simple, reutilizarla en muchos lugares y exponer solo las columnas relevantes a quien la usa.
CREATE VIEW v AS SELECT ... se consulta con SELECT * FROM v como si fuera una tabla, pero el motor expande su definición en tiempo de ejecución.revenue por línea) y lo reutilizas; también ocultas columnas sensibles mostrando solo un subconjunto.vista_top sobre vista_resumen).DROP VIEW IF EXISTS v; CREATE VIEW v AS ...; para poder re-ejecutar el script sin error de "vista ya existe".La sintaxis es CREATE VIEW nombre AS <consulta_SELECT>;. SQLite también admite CREATE VIEW IF NOT EXISTS, pero si vas a redefinir la lógica, ese IF NOT EXISTS NO actualiza una vista existente: por eso el patrón recomendado para scripts reproducibles es borrar y recrear con DROP VIEW IF EXISTS.
Las vistas en SQLite son de solo lectura: no puedes hacer INSERT/UPDATE/DELETE directamente sobre una vista (a menos que definas un INSTEAD OF TRIGGER). Internamente, consultar una vista equivale a sustituir su nombre por su SELECT entre paréntesis; el optimizador luego aplana esa subconsulta, por lo que el rendimiento suele ser idéntico a escribir la consulta a mano.
Puedes nombrar las columnas de la vista de dos formas: con alias dentro del SELECT (SUM(...) AS revenue) o con una lista explícita CREATE VIEW v(col1, col2) AS ....
SELECT d.nombre AS categoria, COUNT(*) AS productos, ROUND(AVG(p.precio), 0) AS precio_prom FROM productos p JOIN categorias d ON p.categoria_id = d.id GROUP BY d.id ORDER BY precio_prom DESC
-- Vista de revenue por línea de detalle (cálculo encapsulado y reutilizable)
DROP VIEW IF EXISTS vista_ventas_linea;
CREATE VIEW vista_ventas_linea AS
SELECT dp.pedido_id,
dp.producto_id,
dp.cantidad * dp.precio_unitario * (1 - dp.descuento) AS revenue
FROM detalle_pedidos dp;
SELECT * FROM vista_ventas_linea ORDER BY revenue DESC LIMIT 5;
-- Vista con join + agregación: revenue total por cliente
DROP VIEW IF EXISTS vista_resumen_cliente;
CREATE VIEW vista_resumen_cliente AS
SELECT c.id,
c.empresa,
c.segmento,
ROUND(SUM(dp.cantidad * dp.precio_unitario * (1 - dp.descuento)), 2) AS revenue_total
FROM clientes c
JOIN pedidos p ON p.cliente_id = c.id
JOIN detalle_pedidos dp ON dp.pedido_id = p.id
GROUP BY c.id, c.empresa, c.segmento;
SELECT * FROM vista_resumen_cliente ORDER BY revenue_total DESC LIMIT 5;
-- Composición: una vista construida SOBRE otra vista
DROP VIEW IF EXISTS vista_resumen_cliente;
CREATE VIEW vista_resumen_cliente AS
SELECT c.id, c.empresa, c.segmento,
ROUND(SUM(dp.cantidad * dp.precio_unitario * (1 - dp.descuento)), 2) AS revenue_total
FROM clientes c
JOIN pedidos p ON p.cliente_id = c.id
JOIN detalle_pedidos dp ON dp.pedido_id = p.id
GROUP BY c.id, c.empresa, c.segmento;
DROP VIEW IF EXISTS vista_top_segmento;
CREATE VIEW vista_top_segmento AS
SELECT segmento, ROUND(SUM(revenue_total), 2) AS revenue
FROM vista_resumen_cliente
GROUP BY segmento;
SELECT * FROM vista_top_segmento ORDER BY revenue DESC;
💡 Para listar las vistas existentes usa SELECT name FROM sqlite_master WHERE type='view';. Recuerda: si una vista A depende de B, debes recrear B antes que A; por eso en un mismo script conviene reconstruir la cadena completa.
| Cláusula / Función | Qué hace |
|---|---|
CREATE VIEW v AS SELECT ... | Crea una tabla virtual basada en una consulta |
CREATE VIEW IF NOT EXISTS v AS ... | Crea solo si no existe (no redefine la lógica) |
DROP VIEW IF EXISTS v | Elimina la vista si existe (patrón idempotente) |
CREATE VIEW v(a,b) AS ... | Nombra explícitamente las columnas |
SELECT ... FROM sqlite_master WHERE type='view' | Lista todas las vistas |
---
← Modificar y borrar estructuras: ALTER, DROP y claves foráneasÍndices: CREATE INDEX →