~/cuaderno / 2019 / entrada-518.md

Traducir SQL a Active Record Query Interface en Ruby on Rails

Publicado 03 julio 2019 2 min de lectura Revisado 14 septiembre 2026
Sql / relacionar y agrupar. Claves, filas y resultados con contexto

Un amigo que estaba trasladando consultas de PHP a Ruby on Rails me pidió ayuda para contar ventas por cliente. La consulta parecía sencilla, pero el ejemplo original mezclaba un JOIN incompleto, sintaxis incorrecta y un GROUP BY ambiguo. Esta es una versión coherente de la operación.

Qué vamos a contar

Queremos los clientes que tienen ventas con un SKU no vacío y no nulo, junto con el número de esas ventas. Suponemos una relación Client has_many :sales y una columna sales.client_id.

SELECT clients.id, clients.name, clients.zipcode,
       clients.state, clients.city,
       COUNT(sales.id) AS number_of_sales
FROM clients
INNER JOIN sales ON sales.client_id = clients.id
WHERE sales.sku IS NOT NULL AND sales.sku <> ''
GROUP BY clients.id, clients.name, clients.zipcode,
         clients.state, clients.city
ORDER BY clients.id ASC;

La misma intención en Active Record

Client.joins(:sales)
      .where.not(sales: { sku: [nil, ''] })
      .select('clients.id, clients.name, clients.zipcode, clients.state, clients.city, COUNT(sales.id) AS number_of_sales')
      .group('clients.id, clients.name, clients.zipcode, clients.state, clients.city')
      .order('clients.id ASC')

Los nombres están cualificados para evitar ambigüedades. La asociación ya establece la condición del JOIN: no necesitamos repetirla con un == de Ruby dentro de SQL.

Cuidado con el orden y los clientes sin ventas

He usado un orden determinista por cliente. Si quieres ordenar por última venta, define explícitamente un agregado como MAX(sales.created_at). Ordenar por una fecha cualquiera dentro de un grupo no expresa bien la operación.

Este INNER JOIN excluye clientes sin ventas válidas. Incluirlos con un contador cero exige un LEFT JOIN y colocar el filtro donde no elimine las filas sin coincidencia.

Consulta la guía oficial de consultas Active Record y verifica el SQL generado con to_sql en la versión de Rails de tu proyecto.

Compartir: X / Twitter LinkedIn Reddit Email
Siguiente comando: volver al archivo o pulsa Ctrl + K

0 comentarios

TIP RÁPIDO

Sé concreto, añade contexto (versión, distro, stack) y si puedes pega logs en bloque de código. Menos drama, más señales.

nginx plesk mariadb logs

Deja una respuesta

NormaRespeto, claridad, y cero spam. El email no se publica.

Consejo: usa bloques de código para logs. Ej: ```log ... ```

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.