'CONCAT columns with Laravel 5 eloquent

Consider me as laravel beginner

The goal is: I have two colums, now I need the id to be prefixed with the component name of same row in the table.

For Example (Working)... I have Mysql like

SELECT CONCAT(components.name," ", components.id) AS ID
FROM   `components` 

And output is

ID

|TestComp 40  |
 -------------
|component 41 |
 -------------
|test 42      |

I need the same in laravel eloquent way, as here Component is Model name. So i tried something like

$comp=Component::select("CONCAT('name','id') AS ID")->get()

but it doesn't work.
I think because the syntax is wrong.
Kindly help me with the correct syntax. Using laravel Models.

Note: I made the above query, referring this as which available on internet.

User::select(DB::raw('CONCAT(last_name, first_name) AS full_name'))


Solution 1:[1]

You need to wrap your query in DB::raw:

$comp = Component::select(DB::raw("CONCAT('name','id') AS ID"))->get()

Also, note because you are doing your query like this, your model might behave differently, because this select removes all other fields from the select statement. So you can't read the other fields from your model without a new query. So ONLY use this for READING data and not MODIFYING data.

Also, to make it in a nice list, I suggest you modify your query to:

$comp = Component::select(DB::raw("CONCAT('name','id') AS display_name"),'id')->get()->pluck('display_name','id');
// dump output to see how it looks.
dd($comp);// array key should be the arrray index, the value the concatted value.

Solution 2:[2]

I came to this post for answers myself. The only problem for me is that the answer didn't really work for my situation. I have numerous table relationships setup and I needed one of the child objects to have a concatenated field. The DB::raw solution was too messy for me. I kept searching and found the answer I needed and feel it's an easier solution.

Instead of DB::raw, I would suggest trying an Eloquent Accessor. Accessors allow you to retrieve model attributes AND to create new ones that are not created by the original model.

For instance, let's say I have a basic USER_PROFILE table. It contains id, first_name, last_name. I have the need to CONCAT the two name attributes to return their user's full name. In the USER_PROFILE Model I created php artisan make:model UserProfile, I would place the following:

class UserProfile extends Model
{

  /**
   * Get the user's full concatenated name.
   * -- Must postfix the word 'Attribute' to the function name
   *
   * @return string
   */

  public function getFullnameAttribute()
  {
      return "{$this->first_name} {$this->last_name}";
  }

}

From here, when I make any eloquent calls, I now have access to that additional attribute accessor.

| id | first_name | last_name |
-------------------------------
| 1  | John       | Doe       |


$user = App\UserProfile::first(); 

$user->first_name;   /** John **/
$user->fullname;    /** John Doe **/

I will say that I did run into one issue though. That was trying to create a modified attribute with the same name, like in your example (id, ID). I can modify the id value itself, but because I declared the same name, it appears to only allow access to that field value and no other field.

Others have said they can do it, but I was unable to solve this questions EXACT problem.

Solution 3:[3]

I working on posgresql and mysql:

DB::raw('CONCAT(member.last_name, \' \', member.first_name) as full_name')

Solution 4:[4]

Here is the example of columns concatenation in Laravel.

I need to search the user by name and I have three columns for the user name (name_first, name_middle, name_last), so I have created a scope in Laravel UserModel which takes $query and user name as the second parameter.

public function scopeFindUserByName($query,$name) {
    // Concat the name columns and then apply search query on full name
    $query->where(DB::raw(
            // REPLACE will remove the double white space with single (As defined)
            "REPLACE(
                /* CONCAT will concat the columns with defined separator */
                CONCAT(
                    /* COALESCE operator will handle NUll values as defined value. */
                    COALESCE(name_first,''),' ',
                    COALESCE(name_middle,''),' ',
                    COALESCE(name_last,'')
                ),
            '  ',' ')"
        ),
    'like', '%' . $name . '%');
}

and you can use this scope anywhere you need to search user by his name, like

UserModel::findUserByName("Max Begueny");

OR

$query = UserModel::query();
$query->findUserByName("Max Begueny");

To check the result of this SQL query just go through from this post. https://stackoverflow.com/a/62296860/11834856

Solution 5:[5]

Scrubbing the Data: Before using Laravel and now, when developing in other languages, I would use CONCAT() on a regular basis. The answers here work to a degree but there still isn't an elegant way to use CONCAT() in Laravel/Eloquent/Query Builder that I have found.

However, I have found that concatenating the cols AFTER returning the results works well for me and is usually very fast - Scrubbing the data - ( unless you have a huge result which should probably be "chunked" anyway for performance purposes ).

foreach($resultsArray AS $row){
    $row['fullname'] = trim($row['firstname']).' '.trim($row['lastname']);
}

This is a tradeoff of course but, personally, I find it to be much more manageable and doesn't limit my use of Eloquent as intended as well as the Query Builder. ( the above is pseudo code - not tested so tweak as needed )

There are other workarounds as well that don't mess with Eloquent/Query Builder functionality such as creating a concatenated col in the table, in this case full_name - save the full name when the record is inserted/updated. This is not uncommon.

Solution 6:[6]

$text = "other";
$limit = 100
public function get_data($text, $limit)
{
    
    $result = $this->select('titulo', 'codigo', DB::Raw("CONCAT(codigo, ' ', titulo_long) AS text_search"))
                ->where('tipo', '=', 2)
                ->having('text_search', 'LIKE', "%$text%")
                ->limit($limit)
                ->get();
    return $result;

}

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Bmoeller
Solution 3 bravohex
Solution 4 Neha Soni
Solution 5
Solution 6 drodriguez