Codeigniter: Join with 'where in' clause - codeigniter

I want to join tables to list books of two categories fiction and romance. How do I do a JOIN with a WHERE IN clause (is that even possible? sorry, noob here)
Here's where I'm stuck at:
$categories = array(10,12);
$query = select()->from('books');
$query->join('genre_map','genre_map.gid IN ('.implode(",", $categories).')');
Jn Table genre_map: bookid, genre_id
Any SQL Query/CodeIgniter help would be much appreciated.

never used codeigniter, but I would say
$categories = array('10', '12');
$this->$db->select('*');
$this->$db->from('books');
$this->$db->join('genre_map','genre_map.bookid = books.bookid');
$this->$db->where_in('genre_map.gid', $categories);
$query = $this->db->get();

$categories = array(10,12);
$query = select()->from('books');
$query->join('genre_map','genre_map.gid IN ('.implode(",", $categories).')');

For codeigniter you can use as:
$categories = array('10', '12');
$this->$db->select('*')->from('books')->join('genre_map','genre_map.bookid = books.bookid')->where_in('genre_map.gid', $categories)->$this->db->get();

Related

AND, OR use In Join query in Codeigniter

How to use Below query in Codeigniter
SELECT * FROM (post) JOIN user ON user.user_id=post.user_id JOIN friend ON (friend.user_id=post.user_id AND friend.friendship_id=1) OR (friend.user_id=1 ANDfriend.friendship_id=post.user_id) WHERE post.type = 'friend' ORDER BY postid desc
You can use this.
$this->db->query(your query);
like this code.
$sql = "SELECT * FROM table WHERE user_id = 1";
$this->db->query($sql);
try this
$query = $this->db
->select('*')
->from('post')
->join('user', 'user.user_id = post.user_id')
->join('friend', 'friend.user_id = (post.user_id AND friend.friendship_id=1) OR (friend.user_id = 1 AND friend.friendship_id = post.user_id)')
->where('post.type', 'friend')
->order_by('postid','DESC')
->get();
$arrResult = $query->result();

Laravel select * where id =(select id )

Using Laravel eloquent how do I make a query like this:
select * from branches where user_id =(select id from users where name ='sara' )
Assuming that you have a user relationship in your Branch model you could use whereHas:
$branches = Branch::whereHas('user', function ($query) {
$query->where('name', 'sara');
})->get();
Update
If you're using v8.57.0 or above, you can now use the whereRelation() method instead:
Branch::whereRelation('user', 'name', 'sara')->get();
$id = Users::select('id')->where('name','sara')->first();
$barnches = branches::where('id',$id)->get();
Here Users and branches are models , first is using for 1 row and get for many rows
I would split it into two queries. First getting the id, then getting the list. Expecting your models to be called "User" and "Branches"
$user = User::where('name', 'sara');
$id = $user->id;
$branches = Branch::where('id', $id);
This site may help you Link
Try this.
$name = 'sara';
$results = BranchModel::whereIn("user_id", function ($query) use ($name) {
$query->select("id")
->from((new UserModel)->getTable())
->where("name", $name);
})->get();
You can use this:
$users = User::whereName("sara")->get()->pluck('id');
Branch::whereIn('user_id',$users)->get();

Laravel Eloquent "WHERE NOT IN"

I'm having trouble to write query in laravel eloquent ORM.
my query is
SELECT book_name,dt_of_pub,pub_lang,no_page,book_price
FROM book_mast
WHERE book_price NOT IN (100,200);
Now I want to convert this query into laravel eloquent.
Query Builder:
DB::table(..)->select(..)->whereNotIn('book_price', [100,200])->get();
Eloquent:
SomeModel::select(..)->whereNotIn('book_price', [100,200])->get();
You can use WhereNotIn in following way also:
ModelName::whereNotIn('book_price', [100,200])->get(['field_name1','field_name2']);
This will return collection of Record with specific fields
I had problems making a sub query until I added the method ->toArray() to the result, I hope it helps more than one since I had a good time looking for the solution.
Example
DB::table('user')
->select('id','name')
->whereNotIn('id', DB::table('curses')->select('id_user')->where('id_user', '=', $id)->get()->toArray())
->get();
Query Builder:
DB::table('book_mast')
->select('book_name','dt_of_pub','pub_lang','no_page','book_price')
->whereNotIn('book_price', [100,200])->get();
Eloquent:
BookMast::select('book_name','dt_of_pub','pub_lang','no_page','book_price')
->whereNotIn('book_price', [100,200])->get();
The dynamic way of implement whereNotIn:
$users = User::where('status',0)->get();
foreach ($users as $user) {
$data[] = $user->id;
}
$available = User::orderBy('name', 'DEC')->whereNotIn('id', $data)->get();
You can use this example for dynamically calling the Where NOT IN
$user = User::where('company_id', '=', 1)->select('id)->get()->toArray();
$otherCompany = User::whereNotIn('id', $user)->get();
You can use WhereNotIn in the following way:
$category=DB::table('category')
->whereNotIn('category_id',[14 ,15])
->get();`enter code here`
You can do following.
DB::table('book_mast')
->selectRaw('book_name,dt_of_pub,pub_lang,no_page,book_price')
->whereNotIn('book_price',[100,200]);
Its simply means that you have an array of values and you want record except that values/records.
you can simply pass a array into whereNotIn() laravel function.
With query builder
$users = DB::table('applications')
->whereNotIn('id', [1,3,5])
->get(); //will return without applications which contain this id's
With eloquent.
$result = ModelClassName::select('your_column_name')->whereNotIn('your_column_name', ['satatus1', 'satatus2']); //return without application which contain this status.
This is my working variant for Laravel 7
DB::table('user')
->select('id','name')
->whereNotIn('id', DB::table('curses')->where('id_user', $id)->pluck('id_user')->toArray())
->get();
$created_po = array();
$challan = modelname::where('fieldname','!=', 0)->get();
// dd($challan);
foreach ($challan as $rec){
$created_po[] = array_push($created_po,$rec->fieldname);
}
$data = modelname::whereNotIn('fieldname',$created_po)->orderBy('fieldname','desc')->with('modelfunction')->get();
or try pluck in laravel
here
DB::table('user')
->select('id','name')
->whereNotIn('id', DB::table('curses')->where('id_user', '=', $id)->pluck('user_id'))
->get();

Laravel pagination not working with group by clause

It seems Laravel pagination does not working properly with group by clause. For example:
$users = Subject::select(DB::raw('subjects.*, count(user_subjects.id) as total_users'))
->join('user_subjects', 'user_subjects.subject_id', '=', 'subjects.id')
->whereNull('user_subjects.deleted_at')
->groupBy('subjects.id')
->orderBy('subjects.updated_at', 'desc')
->paginate(25);
Produced
select subjects.*, count(user_subjects.id) as total_users
from `subjects` inner join `user_subjects` on `user_subjects`.`subject_id` = `subjects`.`id`
where `subjects`.`deleted_at` is null and `user_subjects`.`deleted_at` is null
group by `subjects`.`id`
order by `subjects`.`updated_at` desc
note that, there is no limit clause on the query.
Working fine if no group by clause in the query:
$users = Subject::select(DB::raw('subjects.*, count(user_subjects.id) as total_users'))
->join('user_subjects', 'user_subjects.subject_id', '=', 'subjects.id')
->whereNull('user_subjects.deleted_at')
->orderBy('subjects.updated_at', 'desc')
->paginate(25);
produced the following query:
select subjects.*, count(user_subjects.id) as total_users from `subjects`
inner join `user_subjects` on `user_subjects`.`subject_id` = `subjects`.`id`
where `subjects`.`deleted_at` is null and `user_subjects`.`deleted_at` is null
order by `subjects`.`updated_at` desc
limit 25 offset 0
does anyone has any idea how can i fix this?
Check the documentation
https://laravel.com/docs/5.2/pagination
Currently, pagination operations that use a groupBy statement cannot
be executed efficiently by Laravel. If you need to use a groupBy with
a paginated result set, it is recommended that you query the database
and create a paginator manually.
I know it is an old question, by I am sharing my solution for future reference.
I managed to write a function based on this link which does the heavy job of determining the pagination of a complex query. Just pass the 'QueryBuilder' and it will return the paginated object/collection.
Additionally, this procedure can track and maintain the other parameters except for page=.
public function mergeQueryPaginate(\Illuminate\Database\Eloquent\Builder $query): \Illuminate\Pagination\LengthAwarePaginator
{
$raw_query = $query;
$totalCount = $raw_query->get()->count();
$perPage = request('per-page', 10);
$page = request('page', 1);
$skip = $perPage * ($page - 1);
$raw_query = $raw_query->take($perPage)->skip($skip);
$parameters = request()->getQueryString();
$parameters = preg_replace('/&page(=[^&]*)?|^page(=[^&]*)?&?/', '', $parameters);
$path = url(request()->getPathInfo() . '?' . $parameters);
$rows = $raw_query->get();
$paginator = new LengthAwarePaginator($rows, $totalCount, $perPage, $page);
$paginator = $paginator->withPath($path);
return $paginator;
}
This works for me in laravel 5.2
Select(\DB::RAW("assignment_descendant_child.assignment_descendant_child_id, assignment_descendant_child.assignment_descendant_child_name, COUNT(assignment_descendant.assignment_descendant_id) as xNum"))
->leftJoin(
'assignment_descendant',
'assignment_descendant.assignment_descendant_child_id',
'=',
'assignment_descendant_child.assignment_descendant_child_id'
)
->orderBy('assignment_descendant_child_name')
->groupBy('assignment_descendant_child.assignment_descendant_child_id')
->paginate(\Config::get('constants.paginate_org_index'))
create a database view namedvw_anything. MySql query will be like
create view vw_anything as select subjects.*, count(user_subjects.id) as total_users from subjects inner join user_subjects on user_subjects.subject_id = subjects.id
where subjects.deleted_at is null and user_subjects.deleted_at is null group by subjects.id;
Now create a new model named UserSubModel for this view, protected $table = 'vw_anything';
Now your paginate query will be like UserSubModel::orderBy('subjects.updated_at', 'desc')->paginate(25);
.
To answer this questioin Laravel Pagination group by year and month only
View query will be :
create view vw_anything as select gallery.*, DATE_FORMAT(created_at, "%Y-%m") as tanggal,count(created_at) as jumlah from gallery group by tanggal;
Let you model is VwModel then your paginate query will be
VwModel::where('type','Foto')->orderBy('tanggal','desc')->paginate(2);
This works if you want to group by and paginate.
$code = DB::table('sources')
->select(DB::raw('sources.id_code,sources.title,avg(point) point'))
->join('rating','sources.id_code','rating.id_code')
->groupBy('sources.id_code')
->groupBy('sources.title')
->groupBy('sources.language')
->groupBy('sources.visited')
->paginate(5);

CodeIgniter - Changing a regular query to an active record query

I was wondering if someone could show me how to change the following sql query to codeigniters active record structure?
$query = $this->db->query('SELECT * FROM '.$this->table_name.' WHERE firstname LIKE "%'.$searchterm.'%" OR lastname LIKE "%'.$searchterm.'%"');
return $query->result();
Cheers
Try:
$this->db->like('firstname', $searchterm);
$this->db->or_like('lastname', $searchterm);
$query = $this->db->get($this->table_name);
return $query->result();
$query = $this->db->get($this->table_name)->like('firstname', $searchterm)->or_like('lastname', $searchterm);
For more information on CodeIgniter's database library, see this documentation.

Resources