Laravel whereIn OR whereIn - php

I'm making a products search by filters:
My code:
->where(function($query) use($filter)
{
if(!empty($filter)){
foreach ($filter as $key => $value) {
$f = explode(",", $value);
$query-> whereIn('products.value', $f);
}
}
})
Query:
and (products.value in (Bomann, PHILIPS) and products.value in (red,white))
But I need:
and (products.value in (Bomann, PHILIPS) OR products.value in (red,white))
Is there something similar in Laravel:
orWhereIn

You could have searched just for whereIn function in the core to see that. Here you are. This must answer all your questions
/**
* Add a "where in" clause to the query.
*
* #param string $column
* #param mixed $values
* #param string $boolean
* #param bool $not
* #return \Illuminate\Database\Query\Builder|static
*/
public function whereIn($column, $values, $boolean = 'and', $not = false)
{
$type = $not ? 'NotIn' : 'In';
// If the value of the where in clause is actually a Closure, we will assume that
// the developer is using a full sub-select for this "in" statement, and will
// execute those Closures, then we can re-construct the entire sub-selects.
if ($values instanceof Closure)
{
return $this->whereInSub($column, $values, $boolean, $not);
}
$this->wheres[] = compact('type', 'column', 'values', 'boolean');
$this->bindings = array_merge($this->bindings, $values);
return $this;
}
Look that it has a third boolean param. Good luck.

You have a orWhereIn function in Laravel. It takes the same parameters as the whereIn function.
It's not in the documentation but you can find it in the Laravel API.
See the Laravel 8 orWhereIn documentation.
That should give you this:
$query-> orWhereIn('products.value', $f);

$query = DB::table('dms_stakeholder_permissions');
$query->select(DB::raw('group_concat(dms_stakeholder_permissions.fid) as fid'),'dms_stakeholder_permissions.rights');
$query->where('dms_stakeholder_permissions.stakeholder_id','4');
$query->orWhere(function($subquery) use ($stakeholderId){
$subquery->where('dms_stakeholder_permissions.stakeholder_id',$stakeholderId);
$subquery->whereIn('dms_stakeholder_permissions.rights',array('1','2','3'));
});
$result = $query->get();
return $result;
// OUTPUT #input $stakeholderId = 1
//select group_concat(dms_stakeholder_permissions.fid) as fid, dms_stakeholder_permissionss.rights from dms_stakeholder_permissions where dms_stakeholder_permissions.stakeholder_id = 4 or (dms_stakeholder_permissions.stakeholder_id = 1 and dms_stakeholder_permissions.rights in (1, 2, 3))

Yes, orWhereIn is a method that you can use.
I'm fairly sure it should give you the result you're looking for, however, if it doesn't you could simply use implode to create a string and then explode it (this is a guess at your array structure):
$values = implode(',', array_map(function($value)
{
return trim($value, ',');
}, $filters));
$query->whereIn('products.value', explode(',' $values));

Yes, orWhereIn where clause method exists in Laravel. Please see the below link of official Laravel Query Builder documentation for detailed information.
Documentation Link: https://laravel.com/docs/8.x/queries#additional-where-clauses
There are two ways to get the below output.
and (products.value in (Bomann, PHILIPS) OR products.value in (red,white))
Using orWhereIn
$query = Product::where('color', 'blue')
->whereIn('value', ['Bomann', 'PHILIPS'])
->orWhereIn('value', ['red', 'white'])
->get();
Output:
select * from `products` where `color` = 'blue' and `value` in (Bomann, PHILIPS) OR `value` in (red,white))
Using orWhere and whereIn
$query2 = Product::where('color', 'blue')
->whereIn('value', ['Bomann', 'PHILIPS'])
->orWhere(function ($query) {
$query->whereIn('value', ['Bomann', 'PHILIPS']);
})
->get();
Output:
select * from `products` where `color` = 'blue' and `value` in (Bomann, PHILIPS) OR (`value` in (red,white))

For example, if you have multiple whereIn OR whereIn conditions and you want to put brackets, do it like this:
$getrecord = DiamondMaster::where('is_delete','0')->where('user_id',Auth::user()->id);
if(!empty($request->stone_id))
{
$postdata = $request->stone_id;
$certi_id =trim($postdata,",");
$getrecord = $getrecord->whereIn('id',explode(",", $certi_id))
->orWhereIn('Certi_NO',explode(",", $certi_id));
}
$getrecord = $getrecord->get();

Related

how to use like operator in array laravel 5.2?

I want to add Like operator in array but it gives me error:
Unknown column '0' in 'where clause (admin_id = 2 and 0 = name and Like = %zdgbdsh%) order by id asc limit 10 offset 0)
Here is my query:-
$conditions = array();
if(!empty($data['name'])) {
$conditions = array_merge($conditions,array('name','Like'=>'%'.$data['name'].'%'));
}
And here is my final query:-
$querys = DB::table('users')
->where($conditions)
->skip($iDisplayStart)->take($iDisplayLength)
->OrderBy($orderby,$dir)
->get();
Note: I don't want directly in query like
where('users.name','like','%'.$data['name'].'%');**
I want to do in conditions variable
I am using laravel framework 5.2
It should be:
$conditions=array_merge($conditions,array('name' => 'Like %'.$data['name'].'%'));
Update
I've just realised that will produce name = Like %data%
You can change it to:
$conditions=array_merge($conditions,array('name', '%'.$data['name'].'%'));
and in where use:
->where(join(' LIKE ', $conditions))
This is not the greatest way of applying multiple conditions, But you can always user the whereRaw
so loop through a array with your conditions eg.
$conditions = [];
if (!empty($data['name'])) {
$conditions = array_merge(
$conditions,
["name LIKE '%".$data['name']."%'"]
);
}
$query = DB::table('users');
// apply add raw conditions
foreach($conditions as $condition){ $query->whereRaw($condition); }
$query->skip($iDisplayStart)->take($iDisplayLength)
->OrderBy($orderby,$dir)
->get();
you could also find some packages that will help you out with things like this.
Hope it helps

Laravel dynamic where queries using Query Builder

I am in new in Laravel. I want to make dynamic where queries with laravel query builder.Normally I can make dynamic queries in php
$where = array(
'hello' => 'world'
);
function get($where = null){
if($where == "") $where = "";
//Function which converts where clause into queries
wheretoqueries($where); //converts where clause
$sql = "SELECT * FROM $tbl $where";
return $sql;
}
echo get($where);
If where clause is null queries will be
SELECT * FROM $tbl
If where clause is not null queries will be
SELECT * FROM $tbl WHERE hello = "world"
Laravel orm works fine for where clause if key and value exists
A::where($where)->get();
If where is null following method will not work
You can chain the where queries as:
$query = Model::query();
if (!empty($value)) {
$query->where('column', $value);
}
$query->get();
OR
You can use when method as:
Model::when($value, function ($query) use ($value) {
return $query->where('column', $value);
})
->get();
Try this. If $where variable contain something then the query will execute otherwise it will retrieve all data from A Model.
function get($where = null){
if($where != null){
A::where('field_name', '=', $where)->first();
}else{
A::all();
}
}
Note: if your query return more than one value then you have to use get() method at end of query builder instead of first();
Reference: https://laravel.com/docs/5.3/queries#where-clauses

Laravel Eloquent orWhere Query

Can someone show me how to write this query in Eloquent?
SELECT * FROM `projects` WHERE `id`='17' OR `id`='19'
I am thinking
Project::where('id','=','17')
->orWhere('id','=','19')
->get();
Also my variables (17 and 19) in this case are coming from a multi select box, so basically in an array. Any clues on how to cycle through that and add these where/orWhere clauses dynamically?
Thanks.
You could do in three ways. Assume you've an array in the form
['myselect' => [11, 15, 17, 19], 'otherfield' => 'test', '_token' => 'jahduwlsbw91ihp'] which could be a dump of \Input::all();
Project::where(function ($query) {
foreach(\Input::get('myselect') as $select) {
$query->orWhere('id', '=', $select);
}
})->get();
Project::whereIn('id', \Input::get('myselect'))->get();
$sql = \DB::table('projects');
foreach (\Input::get('myselect') as $select) {
$sql->orWhere('id', '=', $select);
}
$result = $sql->get();
The best approach for this case is using Laravel's equivalent for SQL's IN().
Project::whereIn('id', [17, 19])->get();
Will be the same as:
SELECT * FROM projects WHERE id IN (17, 19)
This approach is nicer and also more efficient - according to the Mysql Manual, if all values are constants, IN sorts the list and then uses a binary search.
In laravel 5 you could do it this way.
$projects = Projects::query();
foreach ($selects as $select) {
$projects->orWhere('id', '=', $select);
}
$result = $projects->get();
This is very useful specially if you have custom methods on your Projects model and you need to query from variable. You cannot pass $selects inside the orWhere method.
public function getSearchProducts($searchInput)
{
$products = Cache::rememberForever('getSearchProductsWithDiscountCalculationproducts', function () {
return DB::table('products_view')->get();
});
$searchProducts = $products->filter(function ($item) use($searchInput) {
return preg_match('/'.$searchInput.'/i', $item->productName) || preg_match('/'.$searchInput.'/i', $item->searchTags) ;
});
$response = ["status" => "Success", "data" => $searchProducts ];
return response(json_encode($response), 200, ["Content-Type" => "application/json"]);
}
use filter functionality for any customize situations.

How to set wild card option in codeigniter like query with associative array?

As title says i can place '%' in a like query of Codeigniter
$this->db->like('title', 'match', 'before');
// Produces: WHERE title LIKE '%match'
for associative array
$array = array('title' => $match, 'page1' => $match, 'page2' => $match);
$this->db->like($array);
// WHERE title LIKE '%match%' AND page1 LIKE '%match%' AND page2 LIKE '%match%'
for more clarification my model has function which handles most of select query in i send an array parameter to retrieve results
function getTableData($table='', $fields='', $like=array(),$like1=array())
{
//Check For like statement
if(is_array($like) and count($like)>0)
$this->db->like($like);
if(is_array($like1) and count($like1)>0)
$this->db->or_like($like1);
//Check For Fields
if($fields!='')
$this->db->select($fields);
else
$this->db->select();
$result = $this->db->get();
//pr($result->result());
return $result;
}
This is my generic function so while sending as parameter or by modifying function how can i use wild card placing third parameter with default 'both' working as it is.
with third parameter i control the placing of % , But when i use a associative array how can i implement wildcard placing in Codeigniter.
How can i use it in associative array for different column.Is it possible?. I know i can use custom query and currently i m using it. For any help Thanks in advance.
I looked core DB_active_rec.php file. Please try this one:
$this->db->like($array, false, 'before');
/system/database/DB_active_rec.php line 571:
/**
* Like
*
* Generates a %LIKE% portion of the query. Separates
* multiple calls with AND
*
* #param mixed
* #param mixed
* #return object
*/
public function like($field, $match = '', $side = 'both')
{
return $this->_like($field, $match, 'AND ', $side);
}
use as many like as you need in your query. E.g:
$this->db->like('title', $title, 'after')->like('page1', $page1)->like('page2', $page2, 'after')->get('table');
You can use like() several times:
$this->db->like('title', 'match');
$this->db->like('page1', 'match');
$this->db->like('page2', 'match');
or if PHP >5 use chained:
$this->db->like('title', 'match')->like('page1', 'match')->like('page2', 'match');
if you have an array of values, use foreach():
//considering $like = array('field' => 'value', 'field2' => 'value2');
foreach ($like as $field=> $value)
{
$this->db->like($field, $value);
}

Grouping WHERE clauses in Codeigniter

I want to produce the following SQL code using Active Records in Codeigniter:
WHERE name != 'Joe' AND (age < 69 OR id > 50)
Doing the following seems to be as far as I can get, I cant figure out how to group them
$this->db->select()->from('users')->where('name !=', 'Joe')->where('age <', 69)->or_where('id <', $id);
Any ideas? My SQL query is too complex so I dont wish to rewrite everything in traditional SQL.
UPDATE
My SQL code is dynamically generated depending on the values of certain parameters passed into the model method. The problem with not being able to use parenthesis causes a problem because the operator precedence is such that AND is evaluated first before OR.
*Here is a chunk of my active records code, where there are some other code before and after it:
... some $this->db->where() ...
... some $this->db->where() ...
if($price_range) {
$price_array = explode('.', $price_range);
for($i = 0; $i < count($price_array); $i++) {
if($i == 0) {
$this->db->where('places.price_range', $price_array[$i]);
} else {
$this->db->or_where('places.price_range', $price_array[$i]);
}
}
}
... some $this->db->where() ...
... some $this->db->where() ...
The problem comes because I am using $this->db->or_where() which introduces a OR clause that throws the operator precedence into disarray without being able to use ( ) to change the order.
** Is there any way to solve this? **
In Codeigniter 3.0.3 you can do it simple like this :
$this->db->select()
->from('users')
->where('name !=', 'Joe')
->group_start() // Open bracket
->where('age <', 69)
->or_where('id <', $id)
->group_end(); // Close bracket
Perhaps it can help
You can use one large string.
$this->db->select()->from('users')->where("name != 'Joe' AND (age < 69 OR id > 50)
");
The grouping of where clauses is not in CI by default. You have to extend the core and add in the ability. I have done so by doing something as follows:
class MY_DB_mysql_driver extends CI_DB_mysql_driver
{
public function __construct($params)
{
parent::__construct($params);
}
/**
* This function will allow you to do complex group where clauses in to c and (a AND b) or ( d and e)
* This function is needed as else the where clause will append an automatic AND in front of each where Thus if you wanted to do something
* like a AND ((b AND c) OR (d AND e)) you won't be able to as the where would insert it as a AND (AND (b...)) which is incorrect.
* Usage: start_group_where(key,value)->where(key,value)->close_group_where() or complex queries like
* open_bracket()->start_group_where(key,value)->where(key,value)->close_group_where()
* ->start_group_where(key,value,'','OR')->close_group_where()->close_bracket() would produce AND ((a AND b) OR (d))
* #param $key mixed the table columns prefix.columnname
* #param $value mixed the value of the key
* #param $escape string any escape as per CI
* #param $type the TYPE of query. By default it is set to 'AND'
* #return db object.
*/
function start_group_where($key,$value=NULL,$escape,$type="AND")
{
$this->open_bracket($type);
return parent::_where($key, $value,'',$escape);
}
/**
* Strictly used to have a consistent close function as the start_group_where. This essentially callse the close_bracket() function.
*/
function close_group_where()
{
return $this->close_bracket();
}
/**
* Allows to place a simple ( in a query and prepend it with the $type if needed.
* #param $type string add a ( to a query and prepend it with type. Default is $type.
* #param $return db object.
*/
function open_bracket($type="AND")
{
$this->ar_where[] = $type . " (";
return $this;
}
/**
* Allows to place a simple ) to a query.
*/
function close_bracket()
{
$this->ar_where[] = ")";
return $this;
}
}
Usage:
group_where_start(key,value)->where(key,value)->group_where_close()
or
complex queries like
open_bracket()->start_group_where(key,value)->where(key,value)->close_group_where()->start_group_where(key,value,'','OR')->close_group_where()->close_bracket() would produce AND ((a AND b) OR (d))
CI3 has all you need!
$this->db->select('*')->from('my_table')
->group_start()
->where('a', 'a')
->or_group_start()
->where('b', 'b')
->where('c', 'c')
->group_end()
->group_end()
->where('d', 'd')
->get();
https://www.codeigniter.com/userguide3/database/query_builder.html#query-grouping
What I've done is duplicate the and clause after the where, which is effectively the same as the long string selection.
$this->db->select()
->from('users')
->where('name !=', 'Joe')
->where('age <', 69)
->or_where('id <', $id)
->where('name !=', 'Joe');
The one large string way is probably better.
Solved. Dynamically generate the SQL query and plug it into $this->db->where(). Thanks guys!

Categories