Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

gregoryvarghese's avatar

How to renumber order by column in database with Laravel

I've been stumped on this and tried everything I can think of but I can't get Laravel to execute a working mysql query to reorder a ordering column when deleting a row.

The sample code below shows hard coded values, but I'm passing in dynamic queries. I've also tested hard coded and dynamic and both seem to fail for me.

Sample Images Table Schema:

| id | project_id | order |

| ------------- | ------------- | ------------- |

| 2 | 10 | 1 |

| 3 | 10 | 2 |

| 4 | 10 | 3 |

| 5 | 10 | 6 |

| 6 | 10 | 7 |

Sample simplified query (which works in mysql):

SET @number = 3; UPDATE images SET order = (@number := @number + 1) WHERE id >2 AND project_id = 10

This works in tinker but not laravel:

DB::unprepared($sql);

Laravel code that doesn't update the database but throws no errors:

 DB::raw($sql);

Other things I've tried which throw errors including saying there's an error in the query:

DB::statement(DB::raw($sql);
DB::statement($sql);
DB::update($sql);
DB::select($sql);

I've also tried splitting it the statements with no luck:

DB::statement("SET @number = 3;");

$sql = 'UPDATE images SET order = (@number := @number + 1) WHERE id >2016 AND project_id = 10';
$update = DB::update($sql);

Any ideas on what I could be doing wrong or is there a better way to accomplish this using Laravel?

Thanks in advance!

0 likes
21 replies
Tray2's avatar

You need to do something like this.

$order = 1;

$records = Model::all();

foreach($records as $row) {
    $row->order = $order;
    $row->update();
    $order++;
}

With the proper search criteria of course.

1 like
Tray2's avatar

Yes it would.

There is no other way as far as I know to do this since you need to increment betweeen each update.

gregoryvarghese's avatar

The SQL query works in mysql, so there's got to be a way to run it through laravel.

Snapey's avatar

I dont understand your thinking... works in tinker but not in Laravel... its the same thing!

Also, you rewrite the order field but on what basis? How do you know what row gets 3, 4 etc

gregoryvarghese's avatar

I don't get it either as that's my understanding as well.

When I put it in a controller, it doesn't seem to update anything. I've debugged it by adding breakpoints and making sure it executes with no errors, but the database is not updated. When I do it in tinker, it updates as expected.

I'm deleting a row and need to renumber the rest. So if id row 3 gets deleted, it starts row 4 becomes 3 and it goes up from there. I have an order by in my actual code. I simplified the example just because I can't get this portion working.

Snapey's avatar

then you need to reorder all the rows starting at 1 and add order by to the update query

Having had the same situation in the past, I've not found reason to renumber since gaps are rarely an issue

gregoryvarghese's avatar

@Snapey, I simplified the example. The real code has the order by and additional filter parameters.

I show the numbers on the frontend in the UI so the gaps do matter, which is an app requirement. Did you update the rows 1 by 1 in Laravel or in mysql like I'm trying to do?

gregoryvarghese's avatar
Level 2

In case anyone runs into this issue, I solved it by putting the sql code into a stored procedure and calling the stored procedure through Laravel. This way, you only need one database call and mysql handles updating the rows.

Snapey's avatar

I simplified the example. The real code has the order by and additional filter parameters.

Risky because you are not actually presenting proper use case and the problem may be with the stuff you thought was irrelevant.

Its also annoying since we're thinking, well how is that supposed to work, instead of thinking about the problem.

Yes I would iterate over the collection in a heartbeat and not sweat it, unless of course you are resequencing 1000's of rows in which case I would apply the number on the front end as a local loop count, not from the database.

Tray2's avatar

What you have done there is instead of letting the webserver access the data base x times you let the database hit itself that amount of times. Sure you save a few milliseconds but you make it harder to maintain since you now have logic in more than one place.

gregoryvarghese's avatar

Thank you both for the feedback!

@Snapey, I apologize for whatever was confusing. I was just looking for help running the sample query in the example.

@Tray2 , I agree with the logic statement, and would prefer to call the query in Laravel and not a stored proc. I've done this same exact thing in .NET and Java in the past with no issues but I just can't seem to make it work in Laravel. I just can't figure out what I'm missing here and was hoping someone would know how to run that query using Laravel. I thought a DB::raw or DB::statement query should do it based on the docs but it doesn't work for me and I don't know why.

I prefer using SQL to re-number over the language based on past experience performance tuning. The DB update is faster than a PHP call and it eliminates the extra network calls from across the servers.

If anyone knows how to run the query in Laravel directly, I'd be much obliged for the help.

Tray2's avatar

I don't think laravel supports pl/sql in any methods that communicates with the database.

Found this regarding Oracle DB might be adaptable to MySQL

$val1 = 20; 

$result = DB::connection('ora_db')->select(
    DB::raw("exec PRW_GENERA_FACTURA(:val1)"), array ('val1' => $val1)
);

return $result;

gregoryvarghese's avatar

Thanks, Tray. I was above to run the stored proc with parameters using DB::statement like so:

DB::statement('call spRenumberComments(?,?)', [$id, $projectid]);

This works with Laravel 5.6 and mysql 5.6.38.

I also put the stored proc into a migration which means I can maintain it through Laravel.

JarekTkaczyk's avatar

@gregoryvarghese here's how you do it in one go, without the need for any DB logic:

$sql = <<<SQL
UPDATE images, (select @number := 3) as var -- inline variable setting 
SET `order` = (@number := @number + 1) 
WHERE id >2016 AND project_id = 10
SQL;

DB::update($sql);
Snapey's avatar

just make sure you don't end up with any injection attacks by not using bindings.

acedesigns's avatar

@gregoryvarghese Hi.

I am having the a similar issue. Do you mind to share some of your code if you still have it?

public function sortCategories(Request $request) {
        $move = $request->desired_position > $request->current_position ? 'down' : 'up';
        
        \DB::select( "UPDATE product_categories SET display_order = 0 WHERE display_order = ". $request->current_position ." AND id = ". $request->category_id  );

        if ($move == 'down') {
            \DB::select(" UPDATE product_categories SET display_order = (display_order - 1) WHERE display_order > ".$request->current_position." AND display_order <= ". $request->desired_position ."  AND id =  " .$request->category_id);

        }

        if ( $move == 'up') {
            \DB::select("UPDATE product_categories SET display_order = (display_order + 1) WHERE display_order >= ". $request->desired_position." AND display_order < ".$request->current_position." AND id = " .$request->category_id);

        }

        \DB::select( "UPDATE product_categories SET display_order = ". $request->desired_position." WHERE display_order = 0 AND id = " . $request->category_id);
        
    }

The above code changes the display_order column in my DB

The issue is that on the front end Laravel does not listen to this code

$categories = ProductCategory::with('products', 'subcategory')->orderBy('display_order', 'desc')->get();
acedesigns's avatar

No it is not. I get my data from a normal Laravel collection. And I display it in a table and loop through it. The issue is that this code does not "work". I want to order the categories from 0,1,2,3,4 ..

$categories = ProductCategory::with('products', 'subcategory')->orderBy('display_order', 'desc')->get();
acedesigns's avatar
https://blogs.wayne.edu/web/2017/03/13/updating-a-database-display-order-with-drag-and-drop-in-sql/

Thats where i got the inspiration and i tried to impliment for Larave;

Please or to participate in this conversation.