Add a new column with a value to the select query in Laravel
Stefan Izdrail
Founder & Senior Architect · 2026-06-29
Title: Adding a Custom Key-Value Pair in Laravel Select Queries
The task of dynamically adding a key-value pair to each record during a select query can be achieved in multiple ways within Laravel. This article will guide you through various approaches, providing you with the necessary code snippets to make it easier for you to integrate the custom column into your project.
1. Adding a Constant Column: You could create a constant array containing all the possible values for the new key and use it in your query as follows (assuming you want an additional column "type" with two possible values - car and truck):
$types = [
'car' => 'car',
'truck' => 'truck',
];
// Your existing query
$items = DB::table('items')
->orderBy('created_at', 'desc')
->join('items_categories', 'items.item_category_id', '=', 'items_categories.category_id')
->select(
'items.id as items___item_id',
'items.item_title as items___item_title',
'items_categories.id as items_categories___category_id',
'items_categories.title as items_categories___category_title'
)
->take(20);
// Add the custom column in your query with a static value for each record
$items = DB::table('items')
->orderBy('created_at', 'desc')
->join('items_categories', 'items.item_category_id', '=', 'items_categories.category_id')
->select(
'items.id as items___item_id',
'items.item_title as items___item_title',
'items_categories.id as items_categories___category_id',
'items_categories.title as items_categories___category_title'
)
->addSelect('DB::raw("type" => (CASE WHEN items_categories.category_title IN (' . implode(",", array_keys($types)) . ') THEN \'car\' ELSE \'truck\' END) AS new_column')
->take(20);
Here, the `addSelect` method allows you to append custom columns. The `TYPE` column will have the value 'car' for trucks and 'truck' otherwise.
2. Using Closure: You can also dynamically set the type value using a closure within your query like this:
$items = DB::table('items')
->orderBy('created_at', 'desc')
->join('items_categories', 'items.item_category_id', '=', 'items_categories.category_id')
->select(
'items.id as items___item_id',
'items.item_title as items___item_title',
'items_categories.id as items_categories___category_id',
'items_categories.title as items_categories___category_title'
)
->addSelect(function ($q) use ($types) {
$type = array_key_exists($q->f('item_category_id'), $types) ? $types[$q->f('item_category_id')] : 'truck';
$q->addSelect(['type' => DB::raw("(CASE WHEN item_category_id IN (SELECT category_id FROM categories WHERE title = 'Truck') THEN \'car\' ELSE \'{$type}\' END) AS new_column"));
})
->take(20);
Here, the closure is used to dynamically set the values for the type column. Firstly, it checks if the current record's category_id is 'truck', and if so, sets its value to 'car'. Otherwise, it uses the previously defined 'types' array to determine the appropriate value.
3. Using Model Mutators: If you want to perform this modification just once instead of repeating the code everywhere it would be better to use a mutator. You can add an accessor named 'type' in your model:
class Item extends Model {
...
public function getTypeAttribute($value) {
if ($this->item_category_id == 1) // Assuming the truck category has ID 1
return "car";
elseif ($this->item_category_id == 2) // Assuming the car category has ID 2
return "truck";
else
return null; // or set it to default value as needed
}
}
After this, your code could be:
$items = Item::all();
This method provides you with a more global solution, allowing you to perform the modification on all items throughout your project without having to repeat the query or manipulate every item.
Summary: There are multiple ways to achieve this task in Laravel, from modifying the initial SQL query to using model mutators for a more global solution. The approach to use would depend on your preference and project requirements. Whichever method you choose, ensure that it is both efficient and maintainable in the long run.