Inicio > Cursos > SQL y Bases de Datos > Vistas y Funciones
SQL y Bases de DatosDiseño y OptimizaciónLección 14 de 20

Vistas y Funciones

Las vistas son consultas guardadas que se comportan como tablas virtuales. Simplifican consultas complejas, añaden una capa de seguridad (ocultando columnas sensibles), y centralizan la lógica de negocio. Las Materialized Views guardan el resultado en disco para consultas muy costosas.

-- Vista básica: encapsular una consulta compleja
CREATE VIEW resumen_pedidos AS
SELECT
  u.id AS user_id,
  u.nombre,
  u.email,
  COUNT(o.id) AS total_pedidos,
  COALESCE(SUM(o.total), 0) AS gasto_total,
  MAX(o.fecha) AS ultimo_pedido
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.nombre, u.email;

-- Usar la vista como si fuera una tabla
SELECT * FROM resumen_pedidos
WHERE gasto_total > 1000
ORDER BY gasto_total DESC;

-- Reemplazar vista existente
CREATE OR REPLACE VIEW resumen_pedidos AS
SELECT u.id AS user_id, u.nombre, u.email,
       COUNT(o.id) AS total_pedidos,
       COALESCE(SUM(o.total), 0) AS gasto_total,
       MAX(o.fecha) AS ultimo_pedido,
       u.activo  -- columna nueva agregada
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.nombre, u.email, u.activo;

-- MATERIALIZED VIEW: guarda el resultado en disco
-- Útil para consultas muy costosas que se consultan frecuentemente
CREATE MATERIALIZED VIEW stats_diarias AS
SELECT
  DATE(fecha) AS dia,
  COUNT(*) AS num_pedidos,
  SUM(total) AS ingresos,
  AVG(total) AS ticket_promedio
FROM orders
GROUP BY DATE(fecha);

-- Refrescar la materialized view (necesario cuando cambian los datos)
REFRESH MATERIALIZED VIEW stats_diarias;
-- Refrescar sin bloquear lecturas (requiere UNIQUE index)
REFRESH MATERIALIZED VIEW CONCURRENTLY stats_diarias;

-- Función PL/pgSQL con parámetros
CREATE OR REPLACE FUNCTION obtener_top_clientes(
  p_limite INTEGER DEFAULT 10,
  p_desde DATE DEFAULT '2024-01-01'
)
RETURNS TABLE(nombre TEXT, email TEXT, gasto DECIMAL)
LANGUAGE plpgsql AS $$
BEGIN
  RETURN QUERY
  SELECT u.nombre::TEXT, u.email::TEXT,
         COALESCE(SUM(o.total), 0) AS gasto
  FROM users u
  LEFT JOIN orders o ON o.user_id = u.id
    AND o.fecha >= p_desde
  GROUP BY u.nombre, u.email
  ORDER BY gasto DESC
  LIMIT p_limite;
END;
$$;

-- Llamar la función
SELECT * FROM obtener_top_clientes(5, '2024-06-01');
ConsejoLas Materialized Views son perfectas para dashboards y reportes que consultan millones de filas. Programa un REFRESH MATERIALIZED VIEW en un cron job nocturno. Para datos en tiempo real, usa vistas normales.
← Transacciones ACIDTriggers →

Practica esta lección

Resuelve los ejercicios del curso de SQL y Bases de Datos en la app, gratis y con corrección automática.

Empezar a practicar