Reputation: 3615
SQL queries are not one of my strong suits, and I have run into a problem that I was able to solve but am hoping to improve and make more efficient. I am using Laravel's Query Builder in these examples but don't mind using a raw request if I have to.
Currently I am making two queries as follows and merging them after.
$acc_id = 10;
$locat_id= 3;
//First get all sites with account id
$allSites = collect(DB::table('sites')->where('acc_id', $acc_id)->get()):
//Next get only sites with account id and connections with current location id
$connectedSites = collect(
DB::table('sites')
->select('sites.id','name','active','url')
->join('connections as conn','sites.id','=','conn.site_id')
->where('acc_id',$acc_id)
->where('conn.locat_id',$locat_id)
->get()
);
//Merge the collections and drop first row with duplicate site_id
$sites = $allSites->merge($connectedSites)->keyBy('id');
return $sites;
So this gives me the desired results. E.g. all the sites that are associated with the account id, and also the connection data for sites associated with both the account and location ids. However, I would like to learn how to do this in one query if possible.
Upvotes: 2
Views: 3575
Reputation: 25906
Try a LEFT JOIN:
$sites = DB::table('sites')
->select('sites.*','name','active','url')
->leftJoin('connections as conn', function($query) use($locat_id) {
$query->on('sites.id', '=', 'conn.site_id')
->where('conn.locat_id', $locat_id);
})
->where('acc_id',$acc_id)
->get();
Upvotes: 3
Reputation: 1446
This can be done with one query, but I use eloquent instead of the query builder. Check out the with() method, it allows you to eager load the relationship.
$sites = Sites::with('connections')->where('acc_id', $acc_id)->get();
Now you can access the connections data from the model instance without needing to do anymore queries.
foreach($sites as $site){
$site->connection->stuff; // No query generated
}
if you need to separate the two that's easy as well.
$connectedSites = $sites->where('connection.locat_id', $locat_id)
// No query generated from the above, but now $connectedSites has all of
// the connected sites
When you get into laravel's collections, you find out that a LOT of queries can be replaced by using them.
https://laravel.com/docs/5.6/collections#available-methods
Upvotes: 0