In Laravel PHP framework you can use a condition inside a where clause, like this (Fluent):
...
->where(function($query) use ($var) {
if(isset($var)) {
$query->where('something', '=', $var);
}
})
->...
So if you do not have a $var variable, the where clause will not be added to the query.
I would like to do the same thing, but with a join clause, so for example join with another table only if $var is set, but this does not work, the query collapses:
...
->join('tableB', function($query) use ($var) {
if(isset($var)) {
$query->on('tableA.id', '=', 'tableB.id');
}
})
->...
Any suggestion?
You don't need to chain all methods on a single cast.
For instance:
// Instantiates a Query object.
$query = Db::table('posts')->where('published', '=', '1');
// Adds conditional join and where
if (Input::has('category')) {
$query->join('categories', 'categories.id', '=', 'post.category_id')
->where('categories.permalink', '=', Input::get('category'));
}
// Adds another clause
$query->order_by('created_at');
// Fecthes results
$results = $query->get()
Related
public function clientcmd()
{
$client = Commande::join('clients', 'commande.id_cli', "=", 'clients.id')
->select('clients.*')
->where('commande.id_cli', '')
->get();
return response()->json($client);
}
I want to select all the client where id client = id cli in command table but that not work they return an empty array
We don't know the data in your table. I assume you want to select fields whose id_cli field is not empty string.
$client = Commande::join('clients', 'commande.id_cli', "=", 'clients.id')
->select('clients.*')
->where('commande.id_cli','!=', '')
->get();
Use Query builder:
use Illuminate\Support\Facades\DB;
$clients = DB::table('clients')
->join('commande', 'commande.id_cli', '=', 'clients.id')
->select('clients.*')
->where(//you can put condition here)
->get();
You can use Client Model to get all client records
$clients = Client::select('*')
->join('commande', 'commande.id_cli', '=', 'clients.id')
->where("clients.id",$client_id) // put your condition here
->get();
I am new to laravel and I am trying to retrieve data from three tables because the user enters 3 information then I use its to determine the row to check login
so I use this way but not work!
I do not know how to send variables in SQL
DB::table('members')
->join(DB::raw('(SELECT FROM members_courses_assign WHERE referenceNumber=>$coursenum,termkey=>$semester) courseA'), function($join) {
$join->on('members.externalPersonKey', '=', 'courseA.externalPersonKey');
})->join(DB::raw('(SELECT courses FROM WHERE referenceNumber=>$coursenum,termkey=>$semester) coursecc '), function($join) {
$join->on('courseA.referenceNumber', '=', 'coursecc.referenceNumber');
})
->where(['jobID' => $jobid])->get();
Try this :
->where('jobID',$jobid)->get();
Here in Laravel Documentation you can find all you need to know about query builder.
To pass variable to inner query (Anonymous functions) you have to pass it with use keyword as described in docs
$yourVariable= "";
DB::table('members')
->join(DB::raw('(SELECT FROM members_courses_assign WHERE referenceNumber=>$coursenum,termkey=>$semester) courseA'), function($join) use($yourVariable) {
$join->on('members.externalPersonKey', '=', 'courseA.externalPersonKey');
})->join(DB::raw('(SELECT courses FROM WHERE referenceNumber=>$coursenum,termkey=>$semester) coursecc '), function($join) use($yourVariable) {
$join->on('courseA.referenceNumber', '=', 'coursecc.referenceNumber');
})
->where(['jobID' => $jobid])->get();
DB::table('members')
->join('members_courses_assign', function($join) use ($coursenum, $semester) {
$join->on('members.externalPersonKey', '=', 'members_courses_assign.externalPersonKey')
->where('referenceNumber', $coursenum)
->where('termkey', $semester);
})
->join('courses', function($join) use ($coursenum, $semester) {
$join->on('members_courses_assign.referenceNumber', '=', 'courses.referenceNumber')
->where('referenceNumber', $coursenum)
->where('termkey', $semester);
})
->where('jobID', $jobid)
->get();
You can refer to Query Builder's advanced join clauses here.
In Laravel we can setup relationships like so:
class User {
public function items()
{
return $this->belongsToMany('Item');
}
}
Allowing us to to get all items in a pivot table for a user:
Auth::user()->items();
However what if I want to get the opposite of that. And get all items the user DOES NOT have yet. So NOT in the pivot table.
Is there a simple way to do this?
Looking at the source code of the class Illuminate\Database\Eloquent\Builder, we have two methods in Laravel that does this: whereDoesntHave (opposite of whereHas) and doesntHave (opposite of has)
// SELECT * FROM users WHERE ((SELECT count(*) FROM roles WHERE user.role_id = roles.id AND id = 1) < 1) AND ...
User::whereDoesntHave('Role', function ($query) use($id) {
$query->whereId($id);
})
->get();
this works correctly for me!
For simple "Where not exists relationship", use this:
User::doesntHave('Role')->get();
Sorry, do not understand English. I used the google translator.
For simplicity and symmetry you could create a new method in the User model:
// User model
public function availableItems()
{
$ids = \DB::table('item_user')->where('user_id', '=', $this->id)->lists('user_id');
return \Item::whereNotIn('id', $ids)->get();
}
To use call:
Auth::user()->availableItems();
It's not that simple but usually the most efficient way is to use a subquery.
$items = Item::whereNotIn('id', function ($query) use ($user_id)
{
$query->select('item_id')
->table('item_user')
->where('user_id', '=', $user_id);
})
->get();
If this was something I did often I would add it as a scope method to the Item model.
class Item extends Eloquent {
public function scopeWhereNotRelatedToUser($query, $user_id)
{
$query->whereNotIn('id', function ($query) use ($user_id)
{
$query->select('item_id')
->table('item_user')
->where('user_id', '=', $user_id);
});
}
}
Then use that later like this.
$items = Item::whereNotRelatedToUser($user_id)->get();
How about left join?
Assuming the tables are users, items and item_user find all items not associated with the user 123:
DB::table('items')->leftJoin(
'item_user', function ($join) {
$join->on('items.id', '=', 'item_user.item_id')
->where('item_user.user_id', '=', 123);
})
->whereNull('item_user.item_id')
->get();
this should work for you
$someuser = Auth::user();
$someusers_items = $someuser->related()->lists('item_id');
$all_items = Item::all()->lists('id');
$someuser_doesnt_have_items = array_diff($all_items, $someusers_items);
Ended up writing a scope for this like so:
public function scopeAvail($query)
{
return $query->join('item_user', 'items.id', '<>', 'item_user.item_id')->where('item_user.user_id', Auth::user()->id);
}
And then call:
Items::avail()->get();
Works for now, but a bit messy. Would like to see something with a keyword like not:
Auth::user()->itemsNot();
Basically Eloquent is running the above query anyway, except with a = instead of a <>.
Maybe you can use:
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
Source: http://laravel.com/docs/4.2/queries#advanced-wheres
This code brings the items that have no relationship with the user.
$items = $this->item->whereDoesntHave('users')->get();
im trying to join two tables post and comment using ORM relations,
$posts = Post::with('comments')->get();
how can i use condition on comments when using with to join tables?
i can use whereHas like
$posts = Post::whereHas('comments', function ($query) {
if(isset($_GET['title']))
$query->where('title', $_GET['title']);
})->get();
but when i use whereHas i wouldn't get the post without any comment in the result
basically i want to use left join with condition on the right table
You can pass a closure to with() method like this:
$posts = Post::with(['comments' => function($q) {
$q->where('column', '=', 'value'); // Put conditions here
}])->get();
Hope this helps!
You need use Closures:
$title = $_GET['title'];
$posts = Post::whereHas('comments', function ($query) use ($title) {
if(!empty($title)) {
$query->where('title', $_GET['title']);
}
})->get();
Reference:
In PHP 5.3.0, what is the function "use" identifier?
I have something like $user->albums()->where('col', NULL), it works fine then I tried to extend it to empty strings with $user->albums()->where('col', NULL)->or_where('col', '') and it's not working.
Also I saw on this post that I could use where_null('col') but it's not working and it's not documented. Any simple method to select where empty or NULL col
Try using orWhereNull for the second clause:
$users = DB::table('users')
->where('col', '=', '')
->orWhereNull('col')
->get();
Or if you have multiple conditions in the query, you have to wrap the two in a closure:
$users = DB::table('users')
->where(function(\Illuminate\Database\Eloquent\Builder $query) {
$query->where('col', '')->orWhereNull('col');
})
->where('col2','val2')
->get();
How about this:
$user->albums()->whereRaw("NOT col > ''")
This way you can check both conditions at the same time
Try this query:
$users = DB::table('users')
->whereRaw('col = "" OR col IS NULL')
->get();
I always encourage to create queries with the main Laravel functions that are most used.
That's why you must have 2 things in mind:
algorithm. key1 = value1 AND key2 = value2 OR key3 = value3. Be very carreful about precedence because in the way I exemplified there will be a main OR not an AND with OR inside
using where(), whereIn(), whereNull and closure instead of whereRaw(). whereRaw is using more memory than any others I mentioned.
So, to resume your answer:
OR condition
$users = DB::table('users')
->where('col', '=', '')
->orWhere('col','=','')
->whereNull('col')
->get();
AND and OR condition
$users = DB::table('users')
->where(function($query) { $query->where('col','=','')->orWhere('col','=','')->whereNull('col'); })
->where('col','=','')
->get();
The below solution is tested on LARAVEL 9. Solution is to add to the App\Providers\AppServiceProvider this piece of code:
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
///...
Builder::macro('whereNullOrEmpty', function ($field) {
return $this->where(function ($query) use ($field) {
return $query->where($field, '=', null)->orWhere($field, '=', '');
});
});
Builder::macro('whereNotNullOrEmpty', function ($field) {
return $this->where(function ($query) use ($field) {
return $query->where($field, '<>', null)->where($field, '<>', '');
});
});
}
//...
}
and then call it like this:
if($nullOrEmpty){
$builder->whereNullOrEmpty('col');
}else{
$builder->whereNotNullOrEmpty('col');
}
You must call both commands:
where($field, '<>', null);
where($field, '<>', '');
because the MySql is handling empty strings and nulls different than a PHP
you also need to wrap those two commands with the closure to tell Eloquent to put generated code in parentheses and isolate MySql code:
(where col = null or where col = '')
Not sure, but this might work:
$user->albums()->where_in('col', array(NULL,''));