¿Cómo ordenar un resultado del generador de consultas de Laravel por varias columnas?

4 minutos de lectura

avatar de usuario
sofía

Quiero ordenar varias columnas en Laravel 4 usando el método orderBy() en Laravel Elocuente. La consulta se generará usando Eloquent así:

SELECT *
FROM mytable
ORDER BY
  coloumn1 DESC, coloumn2 ASC

¿Cómo puedo hacer esto?

  • Muy simple. User::orderBy('name', 'DESC') ->orderBy('email', 'ASC') ->get();

    – Soy la persona más estúpida

    29 de marzo de 2018 a las 9:09

Simplemente invoque orderBy() tantas veces como lo necesites. Por ejemplo:

User::orderBy('name', 'DESC')
    ->orderBy('email', 'ASC')
    ->get();

Produce la siguiente consulta:

SELECT * FROM `users` ORDER BY `name` DESC, `email` ASC

  • Sería bueno si pudiéramos pasar una matriz como: User::orderBy(array('name'=>'desc', 'email'=>'asc'))

    – Josué David

    7 de octubre de 2014 a las 4:24


  • @FireCoding, puedes hacer $user->orders = array(array('column' => 'name', 'direction' => 'desc'), array('column' => 'email', 'direction' => 'asc'));

    – rmóbis

    7 de octubre de 2014 a las 4:47

  • ¿Hay alguna forma de agregar un orderBy en una consulta establecida?

    – Rafael

    16 de enero de 2015 a las 21:43


  • @Rafael, si aún no lo ha ejecutado (llamado get o first), solo llama orderBy en eso. De lo contrario, no.

    – rmóbis

    17 de enero de 2015 a las 6:33

  • De lo contrario, si siempre necesita ordenar por desc, también puede usar la última ().

    – ssi-anik

    10/03/2016 a las 20:51

Puedes hacer lo que @rmobis ha especificado en su respuesta, [Adding something more into it]

Usando order by dos veces:

MyTable::orderBy('coloumn1', 'DESC')
    ->orderBy('coloumn2', 'ASC')
    ->get();

y la segunda forma de hacerlo es,

Usando raw order by:

MyTable::orderByRaw("coloumn1 DESC, coloumn2 ASC");
    ->get();

Ambos producirán la misma consulta de la siguiente manera,

SELECT * FROM `my_tables` ORDER BY `coloumn1` DESC, `coloumn2` ASC

Como @rmobis especificó en el comentario de la primera respuesta, puede pasar como una matriz para ordenar por columna como esto,

$myTable->orders = array(
    array('column' => 'coloumn1', 'direction' => 'desc'), 
    array('column' => 'coloumn2', 'direction' => 'asc')
);

una forma más de hacerlo es iterate en bucle,

$query = DB::table('my_tables');

foreach ($request->get('order_by_columns') as $column => $direction) {
    $query->orderBy($column, $direction);
}

$results = $query->get();

Espero eso ayude 🙂

  • ¿Puedo usar orderByRaw AND orderBy juntos? no parece funcionar para mí, la consulta resultante solo parece respetar orderByRaw

    – Retorno-1

    25 de octubre de 2017 a las 9:56

  • intente poner orderBy primero y luego orderByRaw y vea el resultado @GeorgeAvgoustis

    – Sagar Naliyapara

    25/10/2017 a las 10:00

  • desafortunadamente, esto no se puede hacer, ya que primero debe ser aleatorio y luego ordenado por el calificador final.

    – Retorno-1

    25 de octubre de 2017 a las 10:02

  • Es posible que funcionen juntos porque al aplicar la ordenación de la primera columna no puede ver la ordenación de la segunda columna

    – Sagar Naliyapara

    25 oct 2017 a las 10:05

Utilice order by así:

return User::orderBy('name', 'DESC')
    ->orderBy('surname', 'DESC')
    ->orderBy('email', 'DESC')
    ...
    ->get();

Aquí hay otro truco que se me ocurrió para mi clase de repositorio base donde necesitaba ordenar por un número arbitrario de columnas:

public function findAll(array $where = [], array $with = [], array $orderBy = [], int $limit = 10)
{
    $result = $this->model->with($with);
    $dataSet = $result->where($where)
        // Conditionally use $orderBy if not empty
        ->when(!empty($orderBy), function ($query) use ($orderBy) {
            // Break $orderBy into pairs
            $pairs = array_chunk($orderBy, 2);
            // Iterate over the pairs
            foreach ($pairs as $pair) {
                // Use the 'splat' to turn the pair into two arguments
                $query->orderBy(...$pair);
            }
        })
        ->paginate($limit)
        ->appends(Input::except('page'));

    return $dataSet;
}

Ahora, puedes hacer tu llamada así:

$allUsers = $userRepository->findAll([], [], ['name', 'DESC', 'email', 'ASC'], 100);

$this->data['user_posts'] = User_posts::with(['likes', 'comments' => function($query) { $query->orderBy('created_at', 'DESC'); }])->where('status', 1)->orderBy('created_at', 'DESC')->get();

  • Las respuestas de solo código no se recomiendan en SO, agregue alguna explicación.

    – endo64

    16 mayo 2021 a las 22:57

  • el método que publicaste no funciona. me puedes explicar un poco

    – Mohamed Raza

    18 de mayo a las 14:58

  • Las respuestas de solo código no se recomiendan en SO, agregue alguna explicación.

    – endo64

    16 mayo 2021 a las 22:57

  • el método que publicaste no funciona. me puedes explicar un poco

    – Mohamed Raza

    18 de mayo a las 14:58

¿Ha sido útil esta solución?