viernes, 16 de agosto de 2019

Laravel distinct() with pagination()

Me encontré con esta inusual situación al tratar de usar paginate luego de hacer un distinct, el total de registros y la paginación no coindician con los obtenidos en la consulta, entonces investigando en Internet encontré muchas soluciones pero ninguna de ellas me fue útil.

Decidí encontrar una solución, para ello busque el concepto de distinct y su funcionalidad, luego de saber que la función distinct lo que hace es eliminar los duplicados de una consulta, ejemplo, si selecciono una columna 'text' y si más de un registro en mi base de datos tiene el mismo valor, aunque el id sea distinto, usando distinct solo me va a mostrar una sola descripción, esto aplica para todos los campos seleccionados en mi consulta, es decir, distinct elimina los duplicados de las columnas que seleccione en mi consulta.

Laravel no le otorga a paginate soporte para distinct, luego entonces la función más parecida a distinct es group by que realiza algo más o menos similar, así que para lograr el mismo efecto que tendría un distinct en nuestra consulta es necesario indicar todas las columnas que seleccionamos en nuestra consulta.

Ejemplo:

DB::select('descripcion', 'nombre')->distinct()->paginate(10);

Obtiene los registros de manera correcta, eliminando los duplicados, pero el total de registros y la paginación son incorrectas ya que se eliminan los duplicados.

DB::select('descripcion', 'nombre')->groupBy('descripcion', 'nombre')->paginate(10);

Esta última sería la forma correcta, "simula" distinct, pero el total de registros y la paginación coinciden con los resultados obtenidos