Concat columns using “with()” function in Laravel Eloquent - php

I'm trying to concat two columns from different tables into one single column.
$user = User::with(array('Person'=>function($query){
$query->selectRaw('CONCAT(prefix_person.name, " - ", prefix_user.code) as name, prefix_user.id');
}))->lists('name', 'id');
In my person class I have this method:
public function User()
{
return $this->hasOne('User');
}
And in my user class I have this one:
public function Person()
{
return $this->belongsTo('Person', 'person_id');
}
I get the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'field list' (SQL: select `name`, `id` from `prefix_user`)
When I tried
$user = User::with(array('Person'=>function($query){
$query->selectRaw('CONCAT(prefix_person.name, " - ", prefix_user.code) as name, prefix_user.id')->lists('name', 'id');
}));
I got this error:
I have used the selectRaw a couple of times, but never needed it into a with (join).

The issue is that Eloquent will first query the users table, and only after, the persons table, so one query is not aware of the other and thus concatenating will not work.
You can use the Query Builder to do this using a join. It will be something like it:
$user = DB::table('users as u')
->join('persons as p', 'p.id', '=', 'u.person_id')
->selectRaw('CONCAT(p.name, " - ", u.code) as concatname, u.id')
->lists('concatname', 'u.id');
EDIT:
And, as suggested by #michel-ayres comment, as long as you have an acessor to the field:
public function getFullNameAttribute() {
return $this->attributes['name'] . ' - ' . $this->attributes['code'];
}
you can use your own model to perform the join and listing:
User::join('person','person.id','=','user.person_id')
->select('person.name', 'user.code', 'user.id')
->get()
->lists('full_name', 'id');

You can solve it simply by using simple query,
User::join('persons as p', 'p.id', '=', 'users.person_id')
->get([
'id',
DB::raw('CONCAT(p.name,"-",users.code) as name')
])
->lists('name', 'id');
Or, see another way
User::join('persons as p', 'p.id', '=', 'users.person_id')
->select(
'id',
DB::raw('CONCAT(p.name,"-",users.code) as name')
)
->lists('name', 'id');

You can solve it by using this sample query
->when($request->value != null, fn ($q) => $q->where(DB::raw("CONCAT(col1,'',col2)"), '=', '' . $request->value.
''))

Related

SQLSTATE[42S22]: Column not found: 1054 Unknown column error on laravel eloquent

In my laravel application I have following function.
This will list down my users in a datatable inside a vue component and users are allowed to filter the records by certain parameters.
public function execute()
{
return User::selectRaw('users.id as id, users.first_name as first_name, users.last_name as last_name, users.country_id as country_id, users.email as email')
->selectRaw('departments.name as department_name, departments.department_type_id as department_type_id')
->selectRaw('project_specific_job_titles.title as job_title')
->selectRaw('min(project_track_records.id) as project_user_id')
->selectRaw('COUNT(
DISTINCT(IF(
certificate_project_specific_job_title.certificate_id IS NOT NULL
AND certificate_project_specific_job_title.mandatory = 1,
certificate_project_specific_job_title.certificate_id,
null
))
) AS available_certificate_count')
->selectRaw('(
SELECT count(*) from
(
SELECT certificate_project_specific_job_title.certificate_id from certificate_project_specific_job_title
WHERE certificate_project_specific_job_title.project_specific_job_title_id=project_track_records.project_specific_job_title_id
AND certificate_project_specific_job_title.mandatory = 1
) as certificate_count_sub_query
) as certificate_count
')
->leftJoin('certificate_user', 'certificate_user.user_id', '=', 'users.id')
->join('project_track_records', 'project_track_records.user_id', '=', 'users.id')
->leftJoin('certificate_project_specific_job_title', function ($join) {
$join->on( 'certificate_project_specific_job_title.certificate_id', '=', 'certificate_user.certificate_id')
->whereRaw('certificate_project_specific_job_title.project_specific_job_title_id=project_track_records.project_specific_job_title_id');
})
->leftjoin('project_specific_job_titles', 'project_specific_job_titles.id', '=', 'project_track_records.project_specific_job_title_id')
->leftJoin('departments', 'departments.id', '=', 'project_specific_job_titles.department_id')
->whereNull('project_track_records.deleted_at')
->whereNotNull('project_track_records.accepted_at')
->where('users.first_name', '<>', '')
->where('users.last_name', '<>', '')
->groupBy('users.id','project_track_records.project_specific_job_title_id')
->when(request('search_text'), function ($query) {
$query->where(function ($query) {
$query->whereRaw("CONCAT_WS(' ', `first_name`, `last_name`) like '%".request('search_text')."%'");
});
})
->when(request('employee_type'), function ($query) {
$query->whereIn('users.is_subcontractor', request('employee_type'));
})
->when(request('nationality'), function ($query) {
$query->whereIn('users.country_id', request('nationality'));
});
}
But every time when I try to run this it gives me an sql error saying,
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'project_track_records.project_specific_job_title_id'
In my database, inside my project_track_records table I have project_specific_job_title_id column and even it contains data..
I even tried flushing my database and running migrations multiple times but this kept giving me unknown column error and I'm struggling to find the mistake I'm doing there...
My laravel version is 8.83.9 and php version is 8.1.4

Relationship eloquent in laravel?

In user:
public function posts()
{
return $this->hasMany(Post::class);
}
In post:
public function users()
{
return $this->belongsTo(Users::class);
}
I handle in controller:
$user = Users::find('1')->posts;
Then I get an array and the result returned is exactly what I need.
But when I query this way because I need to get a lot of data, the result is an empty array. What did I do wrong?
In UserController.php:
$listUser = Users::with('posts')
->select('name', 'title')
->where('type', 1)
->get(); // It returns posts as an empty array
Please give me any comments.
You have to select foreign key in posts:
$listUser = Users::select(['id', 'name'])
->with(['posts' => function($query) {
$query->select(['user_id','title']);
}])
->where('type', 1)
->get();
or
$result = User::select(['id', 'name'])
->with(['posts:user_id, title'])
->get();
Your relation is developed with a primary key and in your query you are missing the id to get the values.
$listUser = Users::with('posts')
->select('users.id', 'users.name', 'posts.title')
->where('posts.type', 1)
->get();
If you wish to select only some fields of the related model you can specify it in the with clause like the following. The select clause will work on the User query builder.
$listUser = Users::with('posts:user_id, title')
->select('name')
->where('type', 1)
->get();

How to Join two different tables in Laravel

QueryException in Connection.php line 729:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'site_name' in
'where clause' (SQL: select email_date, url, recipient from
report_list where site_name = mywebsite)
$records = DB::table('report_list')
->select('email_date','url','recipient')
->where('site_name',$site_name)
->get();
return records;
return view('monthlyReport')
->with('records',$records)
->with('site_name',$site_name);
My site_name was on different table and I don't know if I need to put Join or Make a model for this two.
Can someone help me with this query?
First of all You need to add column named "site_name" to your "report_list" table in database.
this query is for you to join 2 tables (here I took example "users" table as second table If your second table is defferent use your) ->
$records = DB::table('report_list')
->join('users', 'report_list.user_id', '=', 'users.id')
->where('report_list.site_name', '=', $site_name);
->select('users.*', 'report_list.email_date','report_list.url','report_list.recipient')
->get();
return view('monthlyReport')
->with(['records' => $records , 'site_name' => $site_name ]);
If you show the tables to see the columns and table names could help you better, while these are some examples:
//Option 1
$results = DB::table('users')
->join('business', 'users.id', '=', 'business.user_id')
->select('users.*', 'business.name', 'business.telephone', 'business.address')
->get();
//Option 2
$results = User::join("business as b","users.id","=","business.user_id")
->select(DB::raw("users.*"), "b.name as business_name", "b.telephone as business_telephone", "b.address as business_address")
->get();
The laravel docs: https://laravel.com/docs/5.6/queries#joins
You should create a model for your other table which I assume it's Site then in the report_list model create a relation method like :
public function sites(){
return $this->hasOne(Site::class);
}
or:
public function sites(){
return $this->hasOne('App\Models\Site);
}
After that in your eloquent query use this :
$records = DB::table('report_list')
->select('email_date','url','recipient')
->whereHas('sites', function($query){
$query->where('site_name',$site_name);
})
->with('sites')
->get();

Laravel create simple drop-down from relationship and concat columns

i want to create simple drop-down inside html code from 2 table which they have single relationship, in my code i cant to get relationship data to concat that with other table columns. for example this is my code:
$user_accounts = UserAccountNumber::with('currencyType')->select('*', DB::raw('CONCAT("CardNumber: ", card_number) AS account_info'))
->whereUserId(Auth::user()->id)
->pluck('account_info', 'id');
this code work fine, but i want to conact some currencyType table columns with UserAccountNumber table and i cant use tableName.columnName into DB::raw()
for example:
$user_accounts = UserAccountNumber::with('currencyType')
->select(
'*',
DB::raw('CONCAT(" CardNumber: ", card_number, "CurrencyType: ", currencyType.title) AS account_info'))
->whereUserId(Auth::user()->id)
->pluck('account_info', 'id');
then i get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'currencyType.currency_type' in 'field list' (SQL: select *, CONCAT("AccountNumber: ",account_number, " CardNumber: ", card_number, "CurrencyType: ", currencyType.currency_type) AS account_info from `user_account_numbers` where `user_id` = 17)
currencyType method in Model:
public function currencyType()
{
return $this->belongsTo(CurrencyType::class, 'currency_type', 'id');
}
Laravel does not use JOINs to do relationships, so you would have to write a specific query for that. Use query builder for that.
Something like this should work:
$user_accounts = DB::table('user_account_numbers')
->join('currencyType', 'user_account_numbers.currency_id', '=', 'currencyType.id')
->select('*', DB::raw('CONCAT(" CardNumber: ", card_number, "CurrencyType: ", currencyType.title) AS account_info'))
->whereUserId(Auth::user()->id)
->get();
I hope you get the idea and can adapt it to suit your database schema.

Eloquent ORM: Complex left join insists on using value as column name

I have the following Eloquent Query in one of my Models:
return self::where('sequence', '=', $sequence)->where('interval', '=', $minutes)
->leftJoin('wallet', 'wallet_stats.wallet_id', '=', 'wallet.id')
->leftJoin('balance', function($join) use ($uid)
{
$join->on('balance.wallet_id', '=', 'wallet_stats.wallet_id')
->on('balance.user_id', '=', $uid);
})
->orderBy('volume', 'ASC')->get(['symbol', 'name', 'volume', 'start_price', 'end_price']);
The problem I'm having with this is the following error message:
Oops! SQLSTATE[42S22]: Column not found: 1054 Unknown column '2' in
'on clause' (SQL: select symbol, name, volume, start_price,
end_price from wallet_stats left join wallet on
wallet_stats.wallet_id = wallet.id left join balance on
balance.wallet_id = wallet_stats.wallet_id and
balance.user_id = 2 where sequence = 0 and interval = 1440
order by volume asc)
For some reason Eloquent insists on using the value of $uid (in the 2nd "on" join condition) as a column name rather than a literal value.
Does anybody know how to get around that and have it accept a literal value in such a join specification?
I can't quite seem to replicate your error however this is what I've used in past instances. Giedrius Kiršys' suggestion in the comment on your question is also good.
return self::where('sequence', '=', $sequence)->where('interval', '=', $minutes)
->leftJoin('wallet', 'wallet_stats.wallet_id', '=', 'wallet.id')
->leftJoin('balance', function($join) use ($uid)
{
$join->on('balance.wallet_id', '=', 'wallet_stats.wallet_id')
->on('balance.user_id', '=', \DB::raw($uid));
})
->orderBy('volume', 'ASC')->get(['symbol', 'name', 'volume', 'start_price', 'end_price']);
This assumes you haven't already imported DB, if you have get rid of the \
Use ->where() for 2nd on clause, such as
->leftJoin('balance', function($join) use ($uid)
{
$join->on('balance.wallet_id', '=', 'wallet_stats.wallet_id');
$join->where('balance.user_id','=', $uid);
})
Or, use the DB::raw() for on clause value
->leftJoin('balance', function($join) use ($uid)
{
$join->on('balance.wallet_id', '=', 'wallet_stats.wallet_id');
$join->on('balance.user_id', '=', DB::raw($uid));
})

Categories