I have a problem with active record in codeigniter.
Here is my sql
$this->db->select('*');
$this->db->from('news as n');
$this->db->join('user as u', 'n.id_user = u.id_user');
$this->db->where('like >','10');
$this->db->limit(10);
$this->db->offset($offset);
$query = $this->db->get();
return $query->result_array();
The "news" table containing column 'like' and table "user" also containing column "like"
and the output is below:
Column 'like' in where clause is ambiguous
SELECT * FROM (`news` as n)
JOIN `user` as u ON `n`.`id_user` = `u`.`id`
WHERE `like` > '10' LIMIT 5
Then I replace
$this->db->where('like >','10');
with
$this->db->where('n.like >','10');
because i want like in news table... But it didn't work
Any solution?
You need to use alias of news table which is n so n.like
$this->db->select('*');
$this->db->from('news as n');
$this->db->join('user as u', 'n.id_user = u.id_user');
$this->db->where('n.like >','10');
$this->db->limit(10);
$this->db->offset($offset);
$query = $this->db->get();
return $query->result_array();
This will still not work as like is a reserved keyword of mysql. You need to change the column name to something else. Read more about mysql reserved keywords here
try something like this
$this->db->select('*');
$this->db->from('news as n');
$this->db->join('user as u', 'n.id_user = u.id_user');
$this->db->where('n.`like` >','10');
$this->db->limit(10);
$this->db->offset($offset);
$query = $this->db->get();
Note : change your column name to something other than reserved keyword
In case you have "like" as column name, put the column in apostrophes(`) like
$this->db->where('`like` >','10');
However is not a good practice to use any mysql reserved keywords as an identifier. Alter the column name to else and if you multiple table using the like column use table alias like.
$this->db->where('n.`like` >','10');
It will be better if you can avoid reserved keywords, so change like column name to likes for instance.
$this->db->where('n.likes >', 10);
Related
I use Sphinx with Yii2 and need to query with filter by jSON field.
$query = new \yii\sphinx\Query();
$query->from('announcements');
$query->addSelect("*");
$query->addSelect(new Expression("IN(filters['color'], 'blue', 'red', 'green') AS f_color"));
$query->where("is_active = 1");
$query->andWhere("f_color = 1");
$announces = $query->all();
There is jSON field filters in my Sphinx index. For example:
[filters] => {"brand":"Toyota","model":"Prius","color":"red","price":"12000"... etc]
It works OK. But now I need to make a pagination... and there is a problem when I try to count records before $query->all()
$count = $query->count(); // Return error "no such filter attribute 'f_color'"
Generated query was:
SELECT COUNT(*) FROM announcements WHERE ( is_active = 1 ) AND ( f_color = 1 )
count() by default replaces the select part with * and this is where your alias is defined hence the error.
There are different ways to achieve it like:
use ActiveDataProvider like described here,
use META information like described here
Since you want to make a pagination I would go with the first example.
I'm working on a laravel application Where I have two very similar QueryBuilder but producing different result in both conditions.
Query 1:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->whereRaw('feed.active <> agents.feed_status')
->pluck('id');
dd(count($ids)); // print 485236
Query 2:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->where('feed.active', '<>', 'agents.feed_status')
->pluck('id');
dd(count($ids)); // print 4259
I would like to know the key difference between these two QueryBuilder. Why is it producing different results, although it seems identical?
And which query returns the correct result? if I would like to find the records from agents where feed_status is not equel to feed.active.
it seem I have got the clarification. Howevere I would like to share my R&D here. Incase if anyone else got the same problem.
I have printed the raw query and get where() seems consider the third parameter as string compare instead of field compare. That's why seems the result is different.
However when we run the query with whereRaw() it's treated this as table field comparision.
Laravel Code:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->whereRaw('feed.active <> agents.feed_status')
->pluck('id');
MySql Query:
"select * from `agents` left join `feed` on `agents`.`identifier` = `feed`.`identifier` where feed.active <> agents.feed_status"
# where feed.active <> agents.feed_status
Laravel Code:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->where('feed.active', '<>', 'agents.feed_status')
->pluck('id');
MySql Query:
"select * from `agents` left join `feed` on `agents`.`identifier` = `feed`.`identifier` where `feed`.`active` <> 'agents.feed_status'"
# where feed.active <> 'agents.feed_status'
Yes, the results were meant to be different.
As where method compares a column with a literal value
->where('table.column', 'cond', 'value')
If you are looking to make comparisons in two columns without using whereRaw method; you should instead use whereColumn method
->whereColumn('table1.column1', 'cond', 'table2.column2')
So my question is:
Is it possible to select all data from different tables in one query?
Example1:
$query = $this->db->get('table1');
$query = $this->db->get('table2');
$query = $this->db->get('table3');
return $query->result();
Example2:
$this->db->select('*');
$this->db->from('table1', 'table2', 'table3');
$query = $this->db->get();
return $query->result();
I think the second exaple is possible. If not i want to ask how you would do that.
Thank you.
It can be done by putting the table names in an arrary
$query = $this->db
->select('*')
->from(['table1', 'table2'])
->get();
return $query->result();
But the number of rows in the result will be the product of the number of rows in each table, i.e. table1 has 3 rows and table2 has 19 you'll get 57 rows in the result. Are you sure that's what you want?
Joins are easy to write and highly efficient. Don't be afraid of them.
I have a drupal site with the search option. If user enters the search keyword, i need to compare that with more than one columns and display the records.
I have tried the following query
$search = 'test';
$sql_query = db_select('logoinfo', 'l')->fields('l');
$or = db_or();
$or->condition('search_field', '%'.db_like($search).'%','LIKE');
$or->condition('companyname', '%'.db_like($search).'%','LIKE');
$sql_query->condition($or);
$selectlogos = $sql_query->execute();
It displays all the records matching the search keyword with the order of auto increment Id asc.
But i want to display the records first which is having both search_field and companyname matches with the keyword, after that other records which is matches with either companyname or search_field. Please advise to achieve this.
Since orderBy requires a field name and can't order by an expression, you'll need to use addExpression to get an alias and then order by that alias. The expression in my example will return 0 if the value is not in both fields and 1 if it is in both fields. As far as I know this should be standard SQL, but it may vary on different database backends; so the expression may need to be adjusted depending on the database you are using.
<?php
$search = 'test';
$sql_query = db_select('logoinfo', 'l')->fields('l');
$or = db_or();
$or->condition('search_field', '%'.db_like($search).'%','LIKE');
$or->condition('companyname', '%'.db_like($search).'%','LIKE');
$sql_query->condition($or);
$safe_search = db_like($search);
$ex_alias = $sql_query->addExpression("l.search_field LIKE '%$safe_search%' AND l.companyname LIKE '%$safe_search%'");
$sql_query->orderBy($ex_alias, 'DESC');
$selectlogos = $sql_query->execute();
?>
$result = mysql_query("SELECT * FROM Volunteers WHERE Volunteers.eventID = " . $var);
$sql = mysql_query("SELECT * FROM Members WHERE Members.pid = " . $temp);
I am also doing or die(mysql_error()) at the end of both statements if that matter. My problem is that the first statement executes perfectly but in that table I store an attribute called pid. So the second statement is supposed to take that and return the row where it equals that pid so I can get the name. I get an error that says unknown column in 'a2' in 'where clause' where a2 the pid attribute returned from the first statement. Thanks for any help!
EDIT: Figured out what was wrong.
Had to write the code like this:
$sql = mysql_query("SELECT * FROM Members WHERE Members.pid = '$temp'") or die(mysql_error());
I think I see what you are trying to do, you can do this in one query, by JOIN-ing the tables together. the SQL query should be something like
SELECT Members.* FROM Members INNER JOIN Volunteers ON Volunteers.eventID=Members.pid WHERE Volunteers.eventID=" . $var
Check out This for a basic introduction to SQL joins.