I have a query that currently works, however, it returns significantly more data than what I need.
Query
$alerts = Criteria::with('coordinate', 'alerts')
->where('user_id', '=', Auth::id())
->get();
For example, if I want to only select the viewed column out of alerts, can this be achieved in this query. I've used ::with to harness Laravel's eager loading feature.
Many thanks.
Use a closure to set the SELECT clause on your query:
$alerts = Criteria::with(['coordinate', 'alerts' => function($query)
{
$query->select('id', 'coordinate_id', 'viewed');
}])
->where('user_id', '=', Auth::id())
->get();
Remember to include the foreign keys, so that Eloquent can properly map them for you.
Related
I have two table (users and messages) .. I wrote a query to get all messages that users sent to me or I sent, using JOIN .. to get all the users I have contacted or they did.
as in the code below:
$users = Message::join('users', function ($join) {
$join->on('messages.sender_id', '=', 'users.id')
->orOn('messages.receiver_id', '=', 'users.id');
})
->where(function ($q) {
$q->where('messages.sender_id', Auth::user()->id)
->orWhere('messages.receiver_id', Auth::user()->id);
})
->orderBy('messages.created', 'desc')
->groupBy('users.id')
->paginate();
The problem here is when records grouped, I'm getting the old message not the new one according to its created_at .. So, I want to get the last record of the grouped records.
It seems like it would make more sense to make use of Eloquent's relationships here so that you can eager load the relationships instead of having to use join and group by:
$messages = Message::with('sender', 'receiver')
->where(function ($query) {
$query->where('sender_id', auth()->id())
->orWhere('receiver_id', auth()->id())
})
->orderByDesc('created') // is this meant to be 'created_at'?
->paginate();
I'm printing some data in mi index.blade.php file but it returns duplicated values. This is my query:
$hist = DB::table('codigo_sisnova')
->join('llamada', 'codigo_sisnova.idPaciente', '=', 'llamada.id_paciente')
->join('medico', 'llamada.id_medico', '=', 'medico.id_medico')
->where('llamada.status_llamada', 'Finalizada')
->where(function($query){
$query->where('llamada.status_pago', '=', 'Sisnova')
->orWhere('llamada.status_pago', '=', 'RedireccionadaSisnova');
})
->distinct()
->get();
I already tried with unique() but it doesn't work too.
EDIT
The relations between tables are one to may from "codigo_sisnova" to "llamada", if I take out the join with the table "medico" the rows keep duplicating
Every row gets a duplicate
You will have multiple codigo_sisnova rows if you are joining tables that have multiple matches on that table. DISTINCT would not eliminate those since the joined data will make it non-distinct in those results. I would recommend trying to use groupBy() to eliminate the redundant rows.
You are missing the group_by statement. Assuming that you have an ID column in codigo_sisnova, besides adding it in a SELECT clause, you need to add it before your get() method :
$hist = DB::table('codigo_sisnova')
->select('codigo_sisnova.id')
->join('llamada', 'codigo_sisnova.idPaciente', '=', 'llamada.id_paciente')
->join('medico', 'llamada.id_medico', '=', 'medico.id_medico')
->where('llamada.status_llamada', 'Finalizada')
->where(function($query){
$query->where('llamada.status_pago', '=', 'Sisnova')
->orWhere('llamada.status_pago', '=', 'RedireccionadaSisnova');
})
->group_by('codigo_sisnova.id')
->get();
I need some help on my query. I use multiple tables with advanced join clauses but it shows invalid count and both has same value:
$parents = DB::table('users')
->select('users.id','users.full_name', 'users.email', 'users.avatar', 'users.signup_date', (DB::raw('count(children.id) as children_no')), (DB::raw('count(invitations.id) as invitations_no')))
->leftJoin('children', function ($join) {
$join->on('users.id', '=', 'children.userid')
->where('children.is_deleted', '=', 0);
})
->leftJoin('invitations', function ($join) {
$join->on('users.id', '=', 'invitations.user_id')
->where('invitations.is_deleted', '=', 0);
})
->where('users.is_admin', '=', 0)
->groupBy('users.id')
->get();
I think you can solve this problem with basic relationships in Laravel + soft deletes on the invitations and children table.
This will make your query less complex and you have the Laravel benefits.
<?php
$users = User::where('is_admin', false)
->has(['invitations', 'children'])
->withCount(['invitations', 'children'])
->get();
This wil select all none admins, with invitations and children.
Make sure you have soft deletes setup on children and invitations.
The withCount will add a count for the related relations.
I have three tables as below:
users
id|name|username|password
roles
id|name
users_roles
id|user_id|role_id
These tables communicate via belongsToMany.
I would like to find a way to select all data in “users” table except ones that their user value of "role_id" is 5 in table “users_roles”.
How can I do it?
You should use whereDoesntHave() to select models that don't have a related model meeting certain criteria:
$users = User::whereDoesntHave('roles', function($q){
$q->where('role_id', 5);
})->get();
Use Laravel's Query Builder:
<?php
$users = DB::table('users')
->leftJoin('users_roles', 'user.id', '=', 'users_roles.user_id')
->where('users_roles.role_id', '!=', 5)
->get();
http://laravel.com/docs/4.2/queries
Or using Eloquent directly:
<?php
$users = User::whereHas('users_roles', function($q)
{
$q->where('role_id', '!=', 5);
})->get();
http://laravel.com/docs/4.2/eloquent#querying-relations
<?php
$users = User::whereHas('roles', function($query) {
$query->where('id', '<>', 5);
})
->orHas('roles','<', 1)
->get();
I think the correct answer is:
User::whereHas('roles', function ($query) {
$query->whereId(5)
}, '=', 0)->get();
This code should send a query that checks if the role with id=5 is related to the user or not.
Edit
While I think this should work but the #lukasgeiter answer is preferable.
In the end both methods use the has() to count the related models by using a subquery in the db query where clause but when you use the whereDoesntHave() it specifies the operator < and the count 1 itself.
You can var_dump(DB::getQueryLog()) in App::after()'s callback to see the actual query.
I have a question regarding join clauses in Eloquent, and whether you can join on a string value rather than a table column.
I have the code below querying a nested set joining parent/child records in a table 'destinations' via a table 'taxonomy'.
The second $join statement in the closure is the one causing an issue; Eloquent assumes this is a column, when I would actually just like to join on t1.parent_type = 'Destination' - ie, t1.parent_type should = a string value, Destination.
$result = DB::connection()
->table('destinations AS d1')
->select(array('d1.title AS level1', 'd2.title AS level2'))
->leftJoin('taxonomy AS t1', function($join) {
$join->on('t1.parent_id', '=', 'd1.id');
$join->on('t1.parent_type', '=', 'Destination');
})
->leftJoin('destinations AS d2', 'd2.id', '=', 't1.child_id')
->where('d1.slug', '=', $slug)
->get();
Is it possible to force Eloquent to do this? I've tried replacing 'Destination' with DB::raw('Destination') but this does not work either.
Thanking you kindly.
Another best way to achieve same is :
$result = DB::connection()
->table('destinations AS d1')
->select(array('d1.title AS level1', 'd2.title AS level2'))
->leftJoin('taxonomy AS t1', function($join) {
$join->on('t1.parent_id', '=', 'd1.id');
$join->where('t1.parent_type', '=', 'Destination');
})
->leftJoin('destinations AS d2', 'd2.id', '=', 't1.child_id')
->where('d1.slug', '=', $slug)
->get();
Replace your on with where
try using DB::raw("'Destination'")