Obtener registros aleatorios de la base de datos en Laravel con Eloquent

Video thumbnail

Cuando trabajas con Laravel, tarde o temprano surge una necesidad muy común: obtener uno o varios registros aleatorios desde la base de datos. Ya sea para mostrar posts relacionados, recomendaciones, contenidos destacados o simplemente variar resultados, Eloquent ofrece varias formas de hacerlo… aunque no todas son igual de recomendables.

En este artículo te voy a mostrar las mejores formas de obtener registros aleatorios en Laravel usando Eloquent, cuándo usar cada una y qué debes tener en cuenta para no cometer errores de rendimiento.

Obtener un registro aleatorio con Eloquent

El método inRandomOrder() junto con first():

$post = Post::inRandomOrder()->first();

Varios registros

Si quieres obtener registros aleatorios en Laravel, tenemos una función llamada orderByRaw() la cual puedes adjuntar a la consulta que ester armando:

$posts = Post::orderByRaw("RAND()")->limit(5)
       ->pluck("title"); //get();
dd($posts);

Unos ejemplos:

Illuminate\Support\Collection {#1433 ?
 #items: array:5 [?
   0 => "Los Arrays en Programación - 18"
   1 => "Dismissible Widget en Flutter"
   2 => "Conectar una app en Flutter a la base de datos Cloud Firestore en Firebase"
   3 => "Ejecutar script automáticamente con Cron en Linux"
   4 => "Escalado y recortando imágenes con Canvas"
 ]
}
Illuminate\Support\Collection {#1433 ?
 #items: array:5 [?
   0 => "El elemento symbol para los SVG en HTML"
   1 => "Desarrollando aplicaciones de Realidad aumentada con Wikitude (parte 1)"
   2 => "Las propiedades flex-grow, flex-shrink y flex-basis"
   3 => "¿Qué es Blender 3D? y primeros pasos (tutoriales)"
   4 => "Problemas con Android Studio y sus proyectos"
 ]
}

Recuerda que el where que está dentro del whereHas nos permite agregar validaciones POR DEFECTO en la relación, es decir, la categoría, de tal manera que en este caso aunque tanto post como category tienen una columna llamada id, por defecto va a buscar el campo (id en este caso) en la tabla de categoría (la relación) si existe, emplea la de la relación, y si n o existe, emplearía la de post y orderByRaw con relaciones.

Lo más interesante es que puedes adjuntarla con whereHas para poder filtrar por alguna relación; por ejemplo, un post tiene una categoría asignada, así que:

$posts = Post::whereHas('category', function ($query) {
           $query->where('id', '<', '10');
       })->orderByRaw("RAND()")->limit(5)
       ->pluck("title"); //get();
   
dd($posts);

Unos ejemplos:

Illuminate\Support\Collection {#1432 ?
 #items: array:5 [?
   0 => "Creando un fondo vivo con CSS"
   1 => "4+1 selectores CSS esenciales al momento de programar"
   2 => "Creando un carrusel animado con CSS"
   3 => "Selectores en JavaScript"
   4 => "Múltiples capas: Efecto de apertura de una puerta con CSS"
 ]
}
Illuminate\Support\Collection {#1432 ?
 #items: array:5 [?
   0 => "Múltiples bordes en un contenedor con CSS"
   1 => "¿Cómo hacer un sistema de grid (rejillas) responsivo casero en CSS?"
   2 => "Plugin para las Cookies en JavaScript"
   3 => "¿Cómo obtener la resolución de pantalla con JavaScript/jQuery?"
   4 => "Formas geométricas con CSS (parte 2)"
 ]

Por supuesto, con limit() puedes limitar o indicar cuantos registros quieres obtener como máximo; esto por darle algunas ideas, pero puedes adaptarle otras funciones.

Por lo demás, puedes aplicar cualquier cantidad de condiciones adicionales antes de usar el método orderByRaw.

Usar inRandomOrder() en Laravel

inRandomOrder() es el método recomendado en versiones modernas de Laravel. Internamente se encarga de aplicar la función aleatoria adecuada según la base de datos (MySQL, PostgreSQL, etc.), lo que hace tu código más portable.

Ejemplo básico para obtener varios registros aleatorios:

 
$posts = Post::inRandomOrder()->get();

Y si quieres limitar la cantidad:

 
$posts = Post::inRandomOrder()->take(5)->get();

Este método es ideal cuando:

  • Trabajas con versiones actuales de Laravel
  • Quieres una solución limpia y legible
  • No necesitas control fino sobre la consulta SQL

Diferencias entre random() e inRandomOrder()

Aquí hay un error bastante común.

  • random() pertenece a las colecciones, no a la consulta SQL.
  • inRandomOrder() actúa directamente en la base de datos.

Por ejemplo:

 
Post::all()->random();

Esto carga todos los registros en memoria y luego selecciona uno al azar. En tablas pequeñas puede funcionar, pero en cuanto el volumen de datos crece, deja de ser una buena idea.

En cambio:

 
Post::inRandomOrder()->first();

Delegas el trabajo al motor de base de datos y evitas consumir memoria innecesariamente.

Obtener varios registros aleatorios con limit() o take()

Uno de los casos más habituales es obtener un conjunto de registros aleatorios, por ejemplo 5 posts distintos cada vez.

Aquí puedes usar indistintamente limit() o take():

 
$posts = Post::inRandomOrder()
    ->limit(5)
    ->pluck('title');

En mis pruebas con datos reales, ejecutar esta consulta varias veces devuelve listas completamente distintas, lo cual es perfecto para secciones dinámicas como “artículos recomendados” o “también te puede interesar”.

Usar orderByRaw('RAND()') para registros aleatorios

Antes de que existiera inRandomOrder() (Laravel 5.2+), la forma clásica de obtener registros aleatorios era usando SQL crudo:

 
$posts = Post::orderByRaw('RAND()')
    ->limit(5)
    ->pluck('title');

Este enfoque sigue siendo totalmente válido, y de hecho lo he utilizado en proyectos reales cuando necesitaba más control sobre la consulta o compatibilidad con código antiguo.

Al ejecutar la consulta varias veces, los resultados cambian realmente, como puedes comprobar fácilmente usando dd().

Cuándo usar orderByRaw() en lugar de inRandomOrder()

orderByRaw('RAND()') es útil cuando:

  • Trabajas con versiones antiguas de Laravel
  • Necesitas una consulta SQL explícita
  • Quieres combinarlo con lógica más compleja

Eso sí, al usar SQL crudo debes tener claro qué base de datos estás utilizando, ya que RAND() es específico de MySQL.

Registros aleatorios en Eloquent usando relaciones (whereHas)

Aquí es donde muchas guías se quedan cortas.

En escenarios reales, no siempre quieres registros aleatorios “sin más”, sino filtrados por una relación. Por ejemplo, posts que pertenezcan a determinadas categorías.

Eloquent permite hacerlo sin ningún problema usando whereHas():

 
$posts = Post::whereHas('category', function ($query) {
        $query->where('id', '<', 10);
    })
    ->orderByRaw('RAND()')
    ->limit(5)
    ->pluck('title');

Lo interesante de este enfoque es que puedes seguir encadenando condiciones antes de aplicar el orden aleatorio. En mi caso, lo he usado para filtrar por categorías concretas y después mostrar contenido variado en cada carga.

Además, el where dentro de whereHas actúa por defecto sobre la tabla relacionada, lo que evita ambigüedades incluso cuando ambas tablas tienen columnas con el mismo nombre, como id.

Filtrar registros antes de aplicar el orden aleatorio

Una buena práctica es aplicar todos los filtros primero y dejar el orden aleatorio para el final. De esta forma:

  • Reduces el conjunto de datos
  • Mejoras el rendimiento
  • Mantienes la consulta clara y mantenible

Esto cobra todavía más importancia cuando trabajas con tablas grandes.

Consideraciones de rendimiento al usar consultas aleatorias

Aquí conviene ser claro: ordenar por RAND() no es gratis.

En tablas con muchos registros, el motor de base de datos tiene que:

  1. Calcular un valor aleatorio por fila
  2. Ordenar todo el conjunto
  3. Devolver los primeros resultados

Si el volumen de datos es muy alto, este tipo de consultas puede volverse costoso. En esos casos, conviene:

  • Limitar siempre el número de registros
  • Filtrar lo máximo posible antes
  • Evaluar estrategias alternativas si el tráfico es elevado

Para la mayoría de proyectos pequeños y medianos, sin embargo, los métodos que hemos visto funcionan perfectamente.

FAQs — Preguntas frecuentes

  • ¿Cómo obtener un solo registro aleatorio en Laravel?
    • Usa Model::inRandomOrder()->first().
  • ¿Cuál es el mejor método para registros aleatorios en Eloquent?
    • inRandomOrder() es el más recomendado en versiones actuales de Laravel.
  • ¿Puedo obtener registros aleatorios usando relaciones?
    • Sí, combinando whereHas() con inRandomOrder() o orderByRaw().
  • ¿RAND() afecta al rendimiento?
    • En tablas grandes puede ser costoso, por lo que conviene limitar y filtrar los resultados.

Conclusión

Obtener registros aleatorios en Laravel usando Eloquent es sencillo si eliges el método adecuado:

  • Usa inRandomOrder() si trabajas con versiones modernas de Laravel.
  • Recurre a orderByRaw('RAND()') si necesitas más control o compatibilidad.
  • Evita random() sobre colecciones en tablas grandes.
  • Combina consultas aleatorias con relaciones y filtros para casos reales.

Con estas técnicas puedes cubrir desde el caso más simple hasta escenarios más avanzados sin complicarte innecesariamente.

Acepto recibir anuncios de interes sobre este Blog.

Aprende a emplear la función orderByRaw oara obtener registros aleatorios de tu base de datos, tanto con la relación directa como de una foránea.

| 👤 Andrés Cruz

🇺🇸 In english