I have a requirement to define composite foreign keys in my Model.Looks it is not supported currently. So, i try to run native queries in my model.
I have two tables(vwAlarm, vwYfUserToSiteMappings) Both has two columns.
CompanyId,SiteCode
I want to return single row, by joining both columns from two tables.
Here is my Model;
class Alarm extends Model
{
protected $table = 'vwAlarm';
protected $primaryKey = 'AlarmId';
..
public function Site()
{
$rec = \DB::table('vwAlarm')
->join('vwYfUserToSiteMappings', 'vwAlarm.SiteCode', '=', 'vwYfUserToSiteMappings.SiteCode')
->join('vwYfUserToSiteMappings','vwAlarm.CompanyId', '=', 'vwYfUserToSiteMappings.CompanyId')
->first();
return $rec;
}
Im getting
QueryException
SQLSTATE[42000]: [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The objects "vwYfUserToSiteMappings" and "vwYfUserToSiteMappings" in the FROM clause have the same exposed names. Use correlation names to distinguish them. (SQL: select top 1 * from [vwAlarm] inner join [vwYfUserToSiteMappings] on [vwAlarm].[SiteCode] = [vwYfUserToSiteMappings].[SiteCode] inner join [vwYfUserToSiteMappings] on [vwAlarm].[CompanyId] = [vwYfUserToSiteMappings].[CompanyId])
How can I correct my query?
You should try this:
$rec = \DB::table('vwAlarm')
->join('vwYfUserToSiteMappings AS vwSiteCode', 'vwSiteCode.SiteCode', '=', 'vwAlarm.SiteCode')
->join('vwYfUserToSiteMappings AS vwCompanyId','vwCompanyId.CompanyId', '=', 'vwAlarm.CompanyId')
->first();
Set alias name for table name like below
$rec = \DB::table('vwAlarm')
->join('vwYfUserToSiteMappings AS vw1', 'vwAlarm.SiteCode', '=', 'vw1.SiteCode')
->join('vwYfUserToSiteMappings AS vw2','vwAlarm.CompanyId', '=', 'vw2.CompanyId')
->first();
Related
I have a AieDetail model as below:
class AieDetail extends \yii\db\ActiveRecord
{
public function getDepts()
{
return $this->hasOne(Department::className(), ['DEPT_CODE' => 'DEPT_CODE']);
}
}
I have this query that I want to use to select distinct COL_ABBREV column on Department table
$aie_detail = AieDetail::find()->alias('AD')
->select(['DEPT.COL_ABBREV'])
->joinWith(['depts DEPT'])
->where(['not',['DEPT.COL_ABBREV' => ['CA']]])
->distinct()
->all();
return $aie_detail;
The value of $aie_detail is a query instead of an array of data. What is the correct approach to get the rows?
$aie_detail = AieDetail::find()
->select([Department::tableName() . '.COL_ABBREV'])
->joinWith('depts')
->where([
'!=',
Department::tableName() . '.COL_ABBREV',
'CA'
])
->distinct()
->asArray()
->all();
if you got any undefined index error include foreign keys used in the relation to the select statement or use leftJoin() method instead of joinWith().
if you want to select more data and distinct based on single column, then add groupBy() with arguments having distinct columns
$aie_detail = AieDetail::find()->alias('AD')
->select('Department.COL_ABBREV')
->joinWith(['depts'])
->where(['not','Department.COL_ABBREV', 'CA'])
->distinct()
->all();
You have to pass in actual table name when using '.' operator in selecting a column in query.
What I'm trying to do is very simple, Running a query with some relations and giving that relation a where clause.the query suppose to get questions with the related relations BUT the where clause on tags tells only get questions with the tag that been sent ($value).
userQuestion Model :
<?php
namespace App;
class userQuestion extends Model
{
protected $table = "question";
public $primaryKey = "question_id";
protected $fillable = ['question_id'];
public function gettags() {
return $this->belongsToMany('App\Profskills','question_profskill',"question_id","prof_id");
}
}
Query
$allquestions = userQuestion::with('getanswer','getusername','getbounty','gettags')
->whereHas('gettags', function($q) use($value) {
$q->where('prof_id', '=', $value);
})
->orderBy('created_at','Desc')
->get();
the problem is it gives me this error
QueryException in Connection.php line 729:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'prof_id' in
where clause is ambiguous (SQL: select * from `question` where exists
(select * from `prof_skills` inner join `question_profskill` on
`prof_skills`.`prof_id` = `question_profskill`.`prof_id` where `question_profskill`.`question_id` = `question`.`question_id` and
`prof_id` = 1) order by `created_at` desc)
the column exist and if i switch the column to qp_id(PrimaryKey) it will work and the Columns are from the pivot table that im trying to access
Did some googling, what i did was :
1-put fillable with 'prof_id' in the model ( since i have a model for the pivot table too , did the same thing)
2-try =>where instead of whereHas
Still stuck,
Thanks for any help!
Add table name with your field as you have prof_id in both tables.
$allquestions = userQuestion::with('getanswer','getusername','getbounty','gettags')
->whereHas('gettags', function($q) use($value) {
$q->where('question_profskill.prof_id', '=', $value); //question_profskill or prof_skills
})
->orderBy('created_at','Desc')->get();
I am using Laravel 5.6 and i have a standard query
Order::where('dict_statuses_id', 1)
->leftJoin('dict_statuses', 'dict_statuses_id', '=', 'dict_statuses.id')
->get();
So i have list of orders with details where status = 1 (new) after join table i see status as New or Complete. Is any way to change this query using whereHas ?
i tried use
Order::whereHas('status', function($q){
$q->where('dict_statuses_id', 1);
})->get();
But no results, in model Order i have
public function status()
{
return $this->hasMany('App\DictStatuses');
}
[Updated]
i have an error:
Column not found: 1054 Unknown column 'dict_statuses.orders_id'
in 'where clause' (SQL: select * from `orders` where exists
(select * from `dict_statuses` where `orders`.`id` = `dict_statuses`.`orders_id` and `dict_statuses_id` = 1)
and `orders`.`deleted_at` is null)
In my table i have table Orders where is field: dict_statuses_id
and table dict_statuses with fields: id, public_name
Why error is about dict_statuses.orders_id
Try Order::has('status')->get();
You can pass in variables to a relationship so you could potentially do.
public function status($id) {
return $this->hasMany(DictStatuses::class)->where('dict_statuses_id', $id);
}
Try defining the local key & foreign key.
$this->hasMany(DictStatuses::class, 'foreign_key', 'local_key');
I think your dict_statuses doesn't have a column called order_id.
Please include that column in your migration
then call
Order::whereHas('status', function($q){
$q->where('dict_statuses_id', 1);
})->get();
in your controller
or change the relation in Order model as
public function status(){
return $this->belongsTo('App\DictStatuses'):
}
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();
Hi I am building an application and I have a table for example projects and then settings. However they do not have a foreign key with each other and i have other tables such as tasks, clients etc. And these have settings which I am planning to save in the settings table.
The settings table has a column of type, which i will fill with the related model name e.g. project. Anyway when i am fetching a project I also want to fetch a the settings where the type = project. So I've tried to do a table join instead however this has thrown the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'project' in 'on clause' (SQL: select * from `projects` inner join `settings` on `type` = `project`)
The code I've used is as follows:
return \Project::()->join('settings', 'type', '=', 'project')->get();
I see what the problem is, its looking for a column called project however there isn't one. I suppose what i want to do is use eloquent and a query function to join the table and then query the settings table where type = project. does anyone know how i can do this?
update from burak answer
I've tried to put this in my model as so so
settings.php
public function sprint() {
return \Setting::where('type', '=', 'sprint')->get();
}
and sprint.php
public function settings() {
return \Setting::where('type', '=', 'sprint')->get();
}
however I get this error Call to undefined method
Illuminate\Database\Eloquent\Collection::addEagerConstraints() and I've called it using this method:
return Sprint::with(['settings'])->get();
what have i done wrong here?
Because you are not referencing the table names and you are comparing columns. Instead, what you need is a where statement within your join condition to compare with a value.
return DB::table('projects')
->join('settings', function ($join) {
$join->where('settings.type', '=', 'project');
})->get();
But you should better get settings and projects one by one as all identical settings columns will be added to your projects rows which is not good.
$data = [];
$data['projects'] = Project::all();
$data['settings'] = Settings::where('type', '=', 'project')->first();
return $data;
Update:
Within your Sprint model
public function scopeWithType()
{
return static::join('settings', function ($join) {
$join->where('settings.type', '=', 'sprint');
});
}
Then within the controller
Sprint::withType()->get();
I have not tried but I think this is what you want. This is how we do subqueries or query joins with where clause.
return \Project::join('settings', function($q) {
$q->where('type', '=', 'project');
})->get();
your code looks for records matching project field in the table settings and type field in the project table, which is not the case.