how can i use multiple where clause In codeigniter? - php

For my database query I have to use multiple where clause query in Codeigniter PHP. I wrote the code like this:
$this->db->and_where_in('category_name,publication_status','home_headline_sub',1);
But this query shows database query error in browser. Then I wrote this query:
$this->db->where('category_name,publication_status','home_headline_sub',1);
But it still give error. Can anyone help me to solve this? Thanks in advance.

You can chain database clauses, so you would write it as
$this->db->where('category_name','case')->where('publication_status','case')->where('home_headline_sub','case');
This would generate a query's WHERE clause as
// WHERE category_name = 'case' AND publication_status = 'case' AND home_headline_sub = 'case'
Documentation here: http://ellislab.com/codeigniter/user-guide/database/active_record.html#chaining

you to use array in it.
$this->db->where(array('category_name'=>case,'publication_status'=>case,'home_headline_sub'=>case));
but I guess you want to check your value against three columns. you can use
$this->db->or_where(array('category_name'=>1,'publication_status'=>1,'home_headline_sub'=>1));
I hope it will help you.

//The simple way
$this->db->where('foo_field', 'foo_value')
->where('bar_field', 'bar_value')
->where('more_field', 'more_value');
//using custom string
//if your sql is really a complex one you can simply write like these
$this->db->where("(foo_filed = 'foo_value') AND (bar_field = 'bar_value') AND (more_field = 'more_value')");
//or may be with something more complex like this
$this->db->where("(foo_filed = 'foo_value') AND ((bar_field = 'bar_value') OR (more_field = 'more_value'))");
//while using a custom string make sure you put them all in the "double quotation marks" and use no ,commas. It is all a single line. The braces are not necessary always but I like to use them.
Documentation

Related

Find inside comma separated values field Laravel 5.1

I Need to check if a variable is present inside a comma separated string in mysql field using querybuilder.
I do this
<?php
$parents = DB::table('categorie')>whereRaw('FIND_IN_SET("$categoria->id", parent)')->get();
but didn't return any value.
You should never put variables in the query yourself. Use bindings instead, this will make sure your parameters are correctly escaped.
<?php
$parents = DB::table('categorie')->whereRaw('FIND_IN_SET(?, parent)', [$categoria->id])->get();
You may debug the query using toSql() method after your query, which becomes
DB::table('categorie')->whereRaw('FIND_IN_SET("$categoria->id", parent)')->toSql();
This will clear it out if $categoria->id is being put in the query or not.
I can't comment yet, hence posting it as an answer.

Query in PHP with 'and' or 'or' as variable

I would like to do search for advanced search. The Search feature has and/or for every category. User can choose any combination of and n or. Here i give the screenshot
I store the and/or into variable call $pil, $pil1,$pil2 and $pil3. And will put them in query. it's better than validate one by one every condition of and/or
So this is my query using postgresql in PHP
$query = pg_query("SELECT evaluationdate,onlinename,channel,topik,reviewername,sourceevaluation,evaluation
from AgentPerformance
where onlinename like '%".$VEOn1."%'
".$pil." reviewername like '%".$VERev1."%'
".$pil1." channel like '%".$VEChan1."%'
".$pil2."sourceevaluation like '%".$VESource1."%'
".$pil3."evaluationdate between '".$VEStart1."' and '".$VEEnd1."'");
EDIT :
The problem now, All the variables must not be empty or the query will be error. any way to trick this?
You've missed some spaces near sourceevaluation and evaluationdate
Try with this query :
$query = pg_query("SELECT evaluationdate,onlinename,channel,topik,reviewername,sourceevaluation,evaluation
from AgentPerformance
where onlinename like '%".$VEOn1."%'
".$pil." reviewername like '%".$VERev1."%'
".$pil1." channel like '%".$VEChan1."%'
".$pil2." sourceevaluation like '%".$VESource1."%'
".$pil3." evaluationdate between '".$VEStart1."' and '".$VEEnd1."'");
Simply. Use validation for each $pil whether it is empty or not. it makes me validate 4 times, but it solves the problem. The syntax error has been solved too

how to get the where clause in string format using CakePHP3 ORM?

In CakePHP3, there is a ORM that helps with building queries.
From the documentation, I can see that
$query = $articles->find(); // build a query that has not run yet
$query->where(['id' => 1]); // Return the same query object
So in this case, I want the string
WHERE `articles`.`id` = 1
After much googling, I found out that there is a way to return just the where clause of a query object.
$query->where(['id' => 1])->clause('where'); // Return the where clause in the form of a QueryExpression
More googling leads me to find out how to get the QueryExpression to spit out string representation
$query->where(['id' => 1])->clause('where')->sql($valueBinder); // Return the where clause in string format
Here is my problem. I don't know what the $valueBinder is supposed to look like. I don't know how to initialize it.
I am also happy not to use ValueBinder as long as I can get the where clause in string format using CakePHP 3 ORM and in the right SQL dialect. Please assume I am using MySQL.
Please advise.
EDIT
I tried to use $query->valueBinder() as the $valueBinder.
It is empty and does not contain the associated c:0 to the value 1.
To directly answer your question, you can get the SQL for any clause this way:
$binder = new \Cake\ORM\ValueBinder();
$query->clause('where')->sql($binder);
That will return the SQL with the correct placeholders, not with the values to be used. The values live in the $binder variable and are used for statement objects.
As I can see, you only wanted to preserve the internal structure of the where clause to pass it to another query in a different request. Your solution is fine, but I'd like to add that you can also encode a full conditions tree from an existing query:
$where = serialize($query->clause('where'));
$anotherQuery->where(unserialize($where)); // A query in another request
In any case, you need to be careful with what you are unserializing as taking it directly from user input will certainly lead to security problems.
You can choose to omit this param if you like. Please see http://api.cakephp.org/3.0/class-Cake.Database.Query.html#_sql
In addition, you can use the Query member function traverse($visitor, $parts) to isolate the where clause. $visitor is a function that takes a value and a clause. You define the behavior of $visitor. $parts is an array of clause names. I suggest passing array('where') into this param.
My workaround is that I store the conditions in json string format.
Using the same example, what I do is
$data['conditions'] = json_encode(['Articles.id' => 1]); // encode into JSON string
$this->DynamicRules->patchEntity($dynamicRule, $data); // use in edit action of DynamicRulesController
then when I need to reuse the conditions, I do:
$articlesTable = TableRegistry::get('Articles');
$query = $articlesTable->find(); // new query for Articles
$rule = json_decode($dynamicRule->conditions, true); // get back the conditions in associative array format
$query->where($rule); // re-assign the conditions back
This got me what I ultimately wanted.

Laravel: How to get last N entries from DB

I have table of dogs in my DB and I want to retrieve N latest added dogs.
Only way that I found is something like this:
Dogs:all()->where(time, <=, another_time);
Is there another way how to do it? For example something like this Dogs:latest(5);
Thank you very much for any help :)
You may try something like this:
$dogs = Dogs::orderBy('id', 'desc')->take(5)->get();
Use orderBy with Descending order and take the first n numbers of records.
Update (Since the latest method has been added):
$dogs = Dogs::latest()->take(5)->get();
My solution for cleanliness is:
Dogs::latest()->take(5)->get();
It's the same as other answers, just with using built-in methods to handle common practices.
Dogs::orderBy('created_at','desc')->take(5)->get();
You can pass a negative integer n to take the last n elements.
Dogs::all()->take(-5)
This is good because you don't use orderBy which is bad when you have a big table.
You may also try like this:
$recentPost = Article::orderBy('id', 'desc')->limit(5)->get();
It's working fine for me in Laravel 5.6
I use it this way, as I find it cleaner:
$covidUpdate = COVIDUpdate::latest()->take(25)->get();
Ive come up with a solution that helps me achieve the same result using the array_slice() method. In my code I did array_slice( PickupResults::where('playerID', $this->getPlayerID())->get()->toArray(), -5 ); with -5 I wanted the last 5 results of the query.
The Alpha's solution is very elegant, however sometimes you need to re-sort (ascending order) the results in the database using SQL (to avoid in-memory sorting at the collection level), and an SQL subquery is a good way to achieve this.
It would be nice if Laravel was smart enough to recognise we want to create a subquery if we use the following ideal code...
$dogs = Dogs::orderByDesc('id')->take(5)->orderBy('id')->get();
...but this gets compiled to a single SQL query with conflicting ORDER BY clauses instead of the subquery that is required in this situation.
Creating a subquery in Laravel is unfortunately not simply as easy as the following pseudo-code that would be really nice to use...
$dogs = DB::subQuery(
Dogs::orderByDesc('id')->take(5)
)->orderBy('id');
...but the same result can be achieved using the following code:
$dogs = DB::table('id')->select('*')->fromSub(
Dogs::orderByDesc('id')->take(5)->toBase(),
'sq'
)->orderBy('id');
This generates the required SELECT * FROM (...) AS sq ... sql subquery construct, and the code is reasonably clean in terms of readability.)
Take particular note of the use of the ->toBase() function - which is required because fromSub() doesn't like to work with Eloquent model Eloquent\Builder instances, but seems to require a Query\Builder instance). (See: https://github.com/laravel/framework/issues/35631)
I hope this helps someone else, since I just spent a couple of hours researching how to achieve this myself. (I had a complex SQL query builder expression that needed to be limited to the last few rows in certain situations).
For getting last entry from DB
$variable= Model::orderBy('id', 'DESC')->limit(1)->get();
Imagine a situation where you want to get the latest record of data from the request header that was just inserted into the database:
$noOfFilesUploaded = count( $request->pic );// e.g 4
$model = new Model;
$model->latest()->take($noOfFilesUploaded);
This way your take() helper function gets the number of array data that was just sent via the request.
You can get only ids like so:
$model->latest()->take($noOfFilesUploaded)->puck('id')
use DB;
$dogs = DB::select(DB::raw("SELECT * FROM (SELECT * FROM dogs ORDER BY id DESC LIMIT 10) Var1 ORDER BY id ASC"));
Dogs::latest()->take(1)->first();
this code return the latest record in the collection
Can use this latest():
$dogs = Dogs::latest()->take(5)->get();

Plain SQL to Codeigniter syntax

I am facing a little trouble with converting this sql to codeigniter syntax. I can use this plain sql and getting results but I have to use return $this->db->query($sql, array($param))->result(); which I guess doesn't return an array (Not sure though, but i keep getting a error "Cannot use object of type stdClass as array in...", and I have no idea if that query can be modified to return an array or any other workaround is available.) Anyway, I guess the best thing to do for me is to follow the CI syntax of query and then use a return $query->result_array(); to get a result array from the query. I know it may be very basic stuff , but somehow I am not able to figure out how to exactly convert this sql to CI syntax. Any help would be appreciated. Thanks. Here is the sql below.
SELECT dirmast.entryID,dirmast.entryTitle,dirmast.entryShortDesc,dirsec.dirsecRefID
FROM dirmast,dirsec
WHERE dirsec.drtext = 'something'
AND dirsec.dirsecRefID = dirmast.entryID
GROUP BY dirsec.dirsecRefID
I think this will do what you want:
$this->db->select('dirmast.entryID,dirmast.entryTitle,dirmast.entryShortDesc,dirsec.dirsecRefID');
$this->db->from('dirmast');
$this->db->join('dirsec','dirsec.dirsecRefID = dirmast.entryID');
$this->db->where('dirsec.drtext','something');
$this->db->group_by('dirsec.dirsecRefID');
If you want your results in an array, you do ->result_array(), if you want it as an object, you do ->result(). Either way, you can use both Active Records and query().

Categories