I have the following Models and related database tables.
Resource
Standard
Resource_Standard
I've given both the tables a belongsToMany correctly and all the naming conventions are correct. I'm trying to do a join on a query, but I keep getting an error that the field I'm checking against doesn't exist. Since I have several values to check against I'm passing them as an array to the query builder. Here is how I'm building my query:
$resource = Resource::where(function($query) use($values)
{
if($values["grade"] != 0)
$query->where('grade_id', '=', $values["grade"]);
if($values['subject'] != 0)
$query->where('subject_id', '=', $values['subject']);
if($values['types'] != '')
{
if(is_array($values['types']) && count($values['types'])> 0)
$query->whereIn('resourcetype_id', $values['types']);
else
$query->where('resourcetype_id', '=', $values['types']);
}
if($values['standards'] != '')
{
if(is_array($values['standards']) && count($values['standards'])> 0)
{
$query->join('resource_standard', 'resource_standard.resource_id', '=', 'resource.id')
->with('standards')->whereIn('resource_standard.standard_id', $values['standards']);
}
else
{
$query->join('resource_standard', 'resource_standard.resource_id', '=', 'resource.id')
->with('standards')->where('resource_standard.standard_id', '=', $values['standards']);
}
}
})->distinct()->take(30)->get();
When there is a standard_id to check against it gives the following error:
{
"error":{
"type":"Illuminate\\Database\\QueryException",
"message":"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'resource_standard.standard_id' in 'where clause' (SQL: select distinct * from `resources` where (`grade_id` = 2 and `subject_id` = 1 and `resource_standard`.`standard_id` in (4832, 4833)) limit 30)",
"file":"\/Users\/luke\/Dropbox\/DEV\/PHP\/4aplus\/4aplus\/vendor\/laravel\/framework\/src\/Illuminate\/Database\/Connection.php","line":555
}
}
You can join using Eloquent model as well. Just use following code:
$resource = Resource::join('resource_standard', 'resource_standard.resource_id', '=', 'resources.id')
Instead of this:
$resource = DB::table('resources')->join('resource_standard', 'resource_standard.resource_id', '=', 'resources.id')
Don't forget to call ->get() at last.
I resolved this by using DB::table rather than the Model. I guess you can't do a join with a model perhaps.
$resource = DB::table('resources')->join('resource_standard', 'resource_standard.resource_id', '=', 'resources.id')
Related
I am trying to use eloquent's with query within a join query to attach the relationships of the table I am joining with however I am faced with the error "Call to undefined method Illuminate\Database\Query\JoinClause::with()"
Hence, how can I use the different with query to attach the relationship data that I need to my target table that I am joining with? (Manual tickets table)
$manual_tickets = ManualTicketLog::select('*')
->where('manual_ticket_logs.user_id','=',$user->id)
->where(function ($checkStatus) {
$checkStatus->where('manual_ticket_logs.status','=','Created')
->orWhere('manual_ticket_logs.status','=','Started');
})
->whereIn('manual_ticket_logs.id', function($q){
$q->select(DB::raw('MAX(id) FROM manual_ticket_logs WHERE (manual_ticket_logs.status != "ClockedOutUser" and manual_ticket_logs.status != "ClockedOutSupervisor" and manual_ticket_logs.status != "AssignByLocation" and manual_ticket_logs.status != "Queued") GROUP BY manual_ticket_logs.manual_ticket_id'));
})
->join('manual_tickets', function ($join) {
$join->on('manual_ticket_logs.manual_ticket_id', '=', 'manual_tickets.id')
->where('manual_tickets.hidden','=',null)
->with('prior_rerouted_ticket');
})
->select('manual_tickets.*', 'manual_ticket_logs.id as manual_ticket_logs_id')
->get();
Portion of code that results in error
->with('prior_rerouted_ticket');
$manual_tickets = ManualTicketLog::select('*')
->where('manual_ticket_logs.user_id', '=', $user->id)
->where(function ($checkStatus) {
$checkStatus->where('manual_ticket_logs.status', '=', 'Created')
->orWhere('manual_ticket_logs.status', '=', 'Started');
})
->whereIn('manual_ticket_logs.id', function ($q) {
$q->select(DB::raw('MAX(id) FROM manual_ticket_logs WHERE (manual_ticket_logs.status != "ClockedOutUser" and manual_ticket_logs.status != "ClockedOutSupervisor" and manual_ticket_logs.status != "AssignByLocation" and manual_ticket_logs.status != "Queued") GROUP BY manual_ticket_logs.manual_ticket_id'));
})
->join('manual_tickets', function ($join) {
$join->on('manual_ticket_logs.manual_ticket_id', '=', 'manual_tickets.id')
->where('manual_tickets.hidden', '=', null);
})
->with('manual_tickets.prior_rerouted_ticket')
->select('manual_tickets.*', 'manual_ticket_logs.id as manual_ticket_logs_id')
->get();
Move relations from join.
Issue has been resolved by restructuring the query. Instead of querying from the manual ticket logs table and then joining it to the manual tickets table whilst trying to find a way to attach the relationship to the manual tickets table, I queried from the manual tickets table first and attached it's relationship before joining it to the manual ticket logs table
$manual_tickets = ManualTicket::select('*')
->where('manual_tickets.hidden','=',null)
->where('manual_tickets.user_id','=',$user->id)
->join('manual_ticket_logs', function ($join) use($user) {
$join->on('manual_ticket_logs.manual_ticket_id', '=', 'manual_tickets.id')
->where('manual_ticket_logs.user_id','=',$user->id)
->where(function ($checkStatus) {
$checkStatus->where('manual_ticket_logs.status','=','Created')
->orWhere('manual_ticket_logs.status','=','Started');
})
->whereIn('manual_ticket_logs.id', function($q){
$q->select(DB::raw('MAX(id) FROM manual_ticket_logs WHERE (manual_ticket_logs.status != "ClockedOutUser" and manual_ticket_logs.status != "ClockedOutSupervisor" and manual_ticket_logs.status != "AssignByLocation" and manual_ticket_logs.status != "Queued") GROUP BY manual_ticket_logs.manual_ticket_id'));
});
})
->with('manual_tickets.prior_rerouted_ticket')
->select('manual_tickets.*', 'manual_ticket_logs.id as manual_ticket_logs_id')
->get();
I want to transform my MySql query into a Query in Laravel but I really don't know how to do this. I don't know how to rename in FROM like in SQL
My query is the following one :
SELECT f2.* FROM formation f2 WHERE f2.theme_id IN
(SELECT f.theme_id FROM user_formation uf JOIN formation f ON uf.formation_id = f.id WHERE uf.user_id = 2)
AND f2.id NOT IN
(SELECT formation_id FROM user_formation WHERE user_id = 2);
I tried something like this but ...
$q = Formation::query()
->from('formation AS f2')
->whereIn('f2.theme_id', function($r)
{
$r->select('f.theme_id')->from('user_formation AS uf')
->join('formation', function($join)
{
$join->on('uf.formation_id', '=', 'f.id')
->where ('uf.user_id', '=', $id)
});
});
->whereNotIn('f2.id', function($s){
$s->select('formation.id')
->from('user_formation')
->where('user_id', '=', $id)
})->get();
thanks for help.
If you want to run this raw query you can run:
$res = DB::select('
SELECT f2.*
FROM formation f2
WHERE f2.theme_id IN
(SELECT f.theme_id FROM user_formation uf JOIN formation f ON uf.formation_id = f.id WHERE uf.user_id = 2)
AND f2.id NOT IN
(SELECT formation_id FROM user_formation WHERE user_id = 2)');
Or you can rewrite this query in laravel query builder Eloquent ORM:
Formations::query()
->whereIn('formations.theme_id', function($q){
$user_formations_table = (new UserFormation)->getTable();
$formation_table = (new Formation)->getTable();
$q->select('paper_type_id')
->from($user_formations_table)
->join($formation_table, "$user_formations_table.formation_id", '=', "$formation_table.id")
->where("$user_formations_table.user_id", 2);
})->whereNotIn('formations.id', function($q){
$user_formations_table = (new UserFormation)->getTable();
$q->select('formation_id')
->where("$user_formations_table.user_id", 2);
})
->get();
Note that I have used models Formations, UserFormation, Formation Because you have used 3 different tables, you should add this models and specify tables to run ORM query
I advice to run first RAW query if there is no another need to run it with Eloquent
Hope this helps you
First of all, you need to fix your code indentations so you don't confuse yourself. Second, you placed semicolon in the wrong places. Third, you need to pass $id inside function because of the variable scope.
$q = Formation::query()
->whereIn('f2.theme_id', function($r) use ($id) {
$r->select('f.theme_id')->from('user_formation AS uf')
->join('formation', function($join) use ($id) {
$join->on('uf.formation_id', '=', 'f.id')
->where('uf.user_id', '=', $id);
}
);
})
->whereNotIn('f2.id', function($s) use ($id) {
$s->select('formation.id')
->from('user_formation')
->where('user_id', '=', $id);
})->get();
Note : If you are using VSCode, I suggest to use PHP Intelephense as it will help with autocomplete, syntax check, etc.
I have 2 tables, customers and customer_invoices, and I want to get all the customers with a condition on their invoices, and select specific columns (customers.id, customers.last_name, and the sum of the total_price of the invoices for each customer), I have this query :
$result = Customer::whereHas('customerInvoices', function(Builder $q) {
$q->where('customer_invoices.status', 1);
})->select([
'customers.id',
'customers.last_name',
\DB::raw('SUM(customer_invoices.total_price) as sum')
])->get();
customerInvoices is the relation :
public function customerInvoices() {
return $this->hasMany(CustomerInvoice::class);
}
I want to use subqueries instead of joins, so here I can't select this \DB::raw('SUM(customer_invoices.total_price) as sum'), or else I get this error of course :
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'customer_invoices.total_price' in 'field list' (SQL: select `customers`.`id`, `customers`.`last_name`, SUM(customer_invoices.total_price) as sum from `customers` where exists (select * from `customer_invoices` where `customers`.`id` = `customer_invoices`.`customer_id` and `customer_invoices`.`status` = 1))"
How can I achieve this without using joins ?
You can use withCount() to get sum from related model as
$result = Customer::select([
'customers.id',
'customers.last_name'
])->withCount([
'customerInvoices as invoice_sum' => function($query) {
$query->select(DB::raw('SUM(total_price)'));
}
])->whereHas('customerInvoices', function(Builder $q) {
$q->where('customer_invoices.status', 1);
})->get();
Another approach to get sum, you can define a hasOne() relation in your Customer model like
public function invoice_sum()
{
return $this->hasOne(CustomerInvoice::class)
->select('customer_id',
DB::raw('sum(total_price)')
)->groupBy('customer_id');
}
And in query builder
$result = Customer::select([
'customers.id',
'customers.last_name',
])->with('invoice_sum')
->whereHas('customerInvoices', function(Builder $q) {
$q->where('customer_invoices.status', 1);
})->get();
As per Eloquent : withCount() overrides the $columns on get() issue first put select() mehtod and then use with() function
Could anybody tell me what error I might have in my laravel query, basically what I want is to list the records of a table whose id is not related in another table. I did it in Mysql with this query: SELECT * FROM item WHERE NOT EXISTS (SELECT null FROM qualifications WHERE grades.item_id = item.id AND qualifications.user_id = 2);
but now I need to do this same query in laravel, I tried it this way:
codigo
and what I get is this syntax error that I do not know how to solve anymore:
error
I am very grateful to anyone who can tell me what I am doing wrong, or in what form I make that query in Laravel.
You can also rewrite your query as left join like
SELECT i.*
FROM item i
LEFT JOIN qualifications q ON q.item_id = i.id AND q.user_id = 2
WHERE q.item_id IS NULL
In query builder you can write it as
DB::table('item as i')
->select('i.*')
->leftJoin('qualifications as q', function ($join) use($user_id) {
$join->on('q.item_id', '=', 'i.id')
->on('q.user_id', '=', $user_id);
})
->whereNull('q.item_id')
->get();
Another approach which i suggest you to go with, is setup your relations and models and do it with eloquent way
class Item extends Model
{
public function qualifications()
{
return $this->hasMany(\App\Models\Qualification::class, 'item_id');
}
}
class Qualification extends Model
{
public function qualifications()
{
return $this->belongsTo(Item::class, 'item_id');
}
}
And then you can use Querying Relationship Absence
Item::whereDoesntHave('qualifications', function ($query) use($user_id) {
$query->where('user_id', '=', $user_id);
})->get();
I have a sql query that is working ok
SELECT
*
FROM
jml_gkb_eventos
WHERE
id IN (SELECT
evento_id
FROM
jml_gkb_etiqueta_evento
WHERE
etiqueta_id IN (SELECT
id
FROM
jml_gkb_etiquetas
WHERE
etiqueta REGEXP ? ) group by evento_id having count(evento_id) = ?);
But i can't figure out how convert this sql query to Eloquent model query. I know that i'm near solution (related with this problem here) and tried some variations of the following code:
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
$cadeiapesquisa = implode('|', $pesquisa);
$contagem = count($pesquisa);
if (Session::get('modo') == 0){
if ( strlen($cadeiapesquisa) > 0 ){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa, $contagem){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa")->groupBy('evento_id')->having('COUNT(evento_id) = '.$contagem);
})->orderBy('id', 'DESC')->paginate(25);
} else {
$this['records'] =Evento::paginate(25);
}
}
I get it working without the ->having() part in inner query, obviosly without the expected return, but without errors.
What i'm doing wrong ?
TIA
JL
[EDIT] - With the code above i get the following error:
I found the problem. It is with the 'count()' part not being processed by eloquent. Placing the count on DB::raw is working as expected at least with the tests i've done. The whole snipet of code with some adjustements is:
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
$cadeiapesquisa = implode('|', $pesquisa);
$contagem = count($pesquisa);
if (Session::get('modo') == 0){
if ( strlen($cadeiapesquisa) > 0 ){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa, $contagem){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa")->groupBy('evento_id')->having(DB::raw("COUNT('etiqueta_id')"), '>=', $contagem );
})->paginate(25);
} else {
$this['records'] = Evento::paginate(25);
}
}
JL