Laravel 5.4 joining two tables - php

I'm quite lost here. I am trying to get the list of people who are on the Records table which aren't on the Profiles tables which has the specific course (e.g Psychology) and year (e.g 2011). So far, this is what I came up with and unfortunately it's not working.
$check = Record::join('Profiles', function ($join) {
$join->on('Records.firstname', '!=', 'Profiles.firstname');
$join->on('Records.lastname', '!=', 'Profiles.lastname');
$join->on('Records.middlename', '!=', 'Profiles.middlename');
})
->select('Records.*', 'Profiles.*')
->where('Records.year', '2011')
->where('Records.course', 'Psychology')
->get();
dump($check);
Is there any way that I can go around about this? I'm new to this. Thanks in advance. Advises and tips on joining tables would be greatly appreciated.

Please try a NOT EXISTS subquery:
use Illuminate\Database\Query\Builder;
$check = \DB::table('Records')
->whereNotExists(function(Builder $query) {
$query->select(\DB::raw(1))
->from('Profiles')
->whereRaw('Records.firstname = Profiles.firstname')
->whereRaw('Records.middlename = Profiles.middlename')
->whereRaw('Records.lastname = Profiles.lastname');
})
->select('firstname', 'middlename', 'lastname')
->where('year', 2011)
->where('course', 'Psychology');
->get();

I would look at doing a left outer join and then selecting the records that have a null profile name.
$check = Record::leftJoin('Profiles', function ($join) {
$join->on('Records.firstname', '=', 'Profiles.firstname');
$join->on('Records.lastname', '=', 'Profiles.lastname');
$join->on('Records.middlename', '=', 'Profiles.middlename');
})
->select('Records.*', 'Profiles.*')
->where('Records.year', '2011')
->where('Records.course', 'Psychology')
->whereNull('Profiles.firstname')
->get();

Related

Trending query Laravel

Right now I have a subquery to get the count of payments for the current month and then getting the 4 products with the highest payment_count. This query works fine but I'm wondering if there's a more simple way to do the same since its getting difficult to read.
$latestPayments = DB::table('payments')
->select('product_id', DB::raw('COUNT(*) as payments_count'))
->whereMonth('created_at', Carbon::now()->month)
->groupBy('product_id');
$trendingProducts = DB::table('products')
->joinSub($latestPayments, 'latest_payments', function ($join) {
$join->on('products.id', '=', 'latest_payments.product_id');
})->orderBy('payments_count', 'DESC')->take(4)->get();
This did it!
$trendingProducts = Product::withCount(['payments' => function($query) {
$query->whereMonth('created_at', Carbon::now()->month);
}])->orderBy('payments_count', 'DESC')->take(4)->get();
If you are using eloquent query with relational database you can do like this:
$latestPaymentWithTrendingProduct = App\Payment::with(['products', function($product) {
$product->orderBy('payments_count', 'DESC')->take(4);
}])->whereMonth('created_at', date('m'))->get()->groupBy('product_id');
This will lessen the code but still do the same thing.

Laravel orderBy using 2 tables?

Please don't tell me to put the orderBy inside the function, because that doesn't work. kill_count and death_count are columns of the roleplay relationship
here is my full code:
$topCredits = Player::whereHas("roleplay", function($q) {
$q->where('government_id', '<', '1');
})->orderBy('credits', 'DESC')->limit(10)->get();
$topKills = Player::whereHas("roleplay", function($q) {
$q->where('government_id', '<', '1')->orderBy('kill_count', 'DESC');
})->limit(10)->get();
$topDeaths = Player::whereHas("roleplay", function($q) {
$q->where('government_id', '<', '1')->orderBy('death_count', 'DESC');
})->limit(10)->get();
Now, the first $topCredits works perfectly, but the bottom 2 don't. They work very well except for the fact it doesn't order by the death_count and kill_count, can anyone help with this? The roleplay is a relationship of hasOne on both sides.
The orderBy in the whereHas would not have any effect on players. Since whereHas is a subquery of Payers.
$topKills = Player::whereHas("roleplay", function($q) {
$q->where('government_id', '<', '1');
})->leftJoin("roleplay","roleplay.player_id","=","players.id")
->select("players.*")
->orderBy('roleplay.kill_count', 'DESC')
->limit(10)
->get();
Hope this helps

Laravel Query where All

I wondered how to make a Where All clause with Laravel
I'm trying to check if the episodes that a user saw are all the episodes of the series.
I'm using the WhereIn clause but i returns the results if i saw one episode of the serie.
$alleps get all the episodes of the serie
$seriessaw get all the episodes a user saw
Thank you for your answers !
$alleps = DB::table('episodes')
->select('episodes.id as ep_id')
->join('seasonsepisodes', 'episodes.id', '=', 'seasonsepisodes.episode_id')
->join('seriesseasons', 'seasonsepisodes.season_id', '=', 'seriesseasons.season_id')
->where('seriesseasons.series_id', '=', $id);
$seriesSaw = DB::table('usersepisodes')
->select('usersepisodes.episode_id as ep_id')
->where('usersepisodes.user_id', '=', Auth::user()->id)
->whereIn('usersepisodes.episode_id', $alleps)
->get();
I think you would need to set a having clause which would force records to only return if there's the same amount of records as there are amount of episodes.
$seriesSaw = DB::table('usersepisodes')
->select('usersepisodes.episode_id as ep_id')
->where('usersepisodes.user_id', '=', Auth::user()->id)
->whereIn('usersepisodes.episode_id', $alleps)
->having(\DB::raw('count(*)'), count($alleps))
->get();
You should note however that this would likely break if there's any possibility of having duplicates in the userepisodes table.
When you use WhereIn, you have to pass an array as the second parameter.
$alleps = DB::table('episodes')
->select('episodes.id as ep_id')
->join('seasonsepisodes', 'episodes.id', '=', 'seasonsepisodes.episode_id')
->join('seriesseasons', 'seasonsepisodes.season_id', '=', 'seriesseasons.season_id')
->where('seriesseasons.series_id', '=', $id)->get()->toArray();
$seriesSaw = DB::table('usersepisodes')
->select('usersepisodes.episode_id as ep_id')
->where('usersepisodes.user_id', '=', Auth::user()->id)
->whereIn('usersepisodes.episode_id', $alleps)
->get();

cant get the data I want from two different tables using Laravel

I have a table called instructor_class: user_id, class_id and I have another table classes: id, time, active.
I would like to show classes for a single user but only those classes that active is 0 or 1.
My current code looks like this:
return InstructorClass::with('classes.session')->where('user_id', '=', $userId)->get();
This code is displaying me everything, then I tried the following code:
$active = 1;
return InstructorClass::with(['classes' => function ($q) use ($active) {
$q->where('active', '=', $active); // '=' is optional
}])
->where('user_id', '=', $userId)
->get();
This again returns me same records, but of course the class property is null for each record, which at some point looks correct, but my point is if the 'active' field does not corresponds at the classes table do not show the record, seems like the where() stm within with() is optional..
I am kinda stuck here...
Would appreciate your help, opinions!
You can use ::has('classes') to only return the models that have related classes
return InstructorClass::has('classes')->with(['classes' => function ($q) use ($active) {
$q->where('active', $active);
}])
->where('user_id', '=', $userId)
->get();
Never thought it could be this simple:
return InstructorClass::with('classes.session')
->join('classes', 'classes.id', '=', 'instructor_class.class_id')
->where('classes.active', '=', 1)
->where('user_id', '=', $userId)
->get();

selects, joins, & wheres in Laravel

I'm trying to select specific columns from two tables however when I add the ->select() method into my query, I get an error.
If I leave out the ->select() method, I get a valid resultset and everything works, but adding the select breaks it. Sadly the error reported has nothing to do with the query and is useless to me.
Here is the code that works:
$notifications = DB::table('notifications')
->join('notifications_pivot', function($join)
{
$join->on('notifications.id', '=', 'notifications_pivot.notification_id')
->where('notifications_pivot.user_id', '=', Session::get('id'))
->where('notifications_pivot.is_read', '=', 'N');
})
->get();
Now here's the code that breaks:
$notifications = DB::table('notifications')
->join('notifications_pivot', function($join)
{
$join->on('notifications.id', '=', 'notifications_pivot.notification_id')
->where('notifications_pivot.user_id', '=', Session::get('id'))
->where('notifications_pivot.is_read', '=', 'N');
})
->select(DB::raw('notifications.id, notifications.subject, notifications.message, notifications.url,
notifications.start_date, notifications.end_date, notifications.access_role_id, notifications_pivot.id,
notifcations_pivot.notification_id, notifications_pivot.user_id, notifications_pivot.is_read'))
->get();
It's times like these when I wish I could just write straight SQL and parse the query!
Any suggestions?
Take out the DB::raw() and just pass the fields you want as parameters.
If that doesn't work, the Laravel log at app/storage/logs/laravel.log may provide more insight.
$notifications = DB::table('notifications')
->join('notifications_pivot', function($join)
{
$join->on('notifications.id', '=', 'notifications_pivot.notification_id')
->where('notifications_pivot.user_id', '=', Session::get('id'))
->where('notifications_pivot.is_read', '=', 'N');
})
->select('notifications.id', 'notifications.subject', 'notifications.message', 'notifications.url', 'notifications.start_date', 'notifications.end_date', 'notifications.access_role_id', 'notifications_pivot.id', 'notifcations_pivot.notification_id', 'notifications_pivot.user_id', 'notifications_pivot.is_read')
->get();

Categories