kohana orm join duplicate objects result - orm

I'm trying to query the country table with the below query to print all countries with the corresponding cities. Now i'm getting a duplicated country object for each city instead of have one country object for all cities.
$all = ORM::factory('country')->select('cities.*')->join('cities','LEFT')->on('country.id', '=', 'country_id' )->find-all();
foreach ($all as $country) {
echo $caountry->name;
foreach($country->cities as $city ){
echo $city->name;
}
}
Appreciate your help,
AA

If you are using MySQL and only need the name of the city, you can use GROUP_CONCAT function and then convert it to array using PHP's explode.
$all = ORM::factory('country')
->select('country.name',DB::epxr('GROUP_CONCAT(cities.name) AS cities'))
->join('cities','LEFT')
->on('country.id', '=', 'country_id' )
->group_by("country.id")
->find-all();
foreach ($all as $country) {
echo $country->name;
foreach(explode(",",$country->cities) as $city ){
echo $city;
}
}

Related

how to select query tables column with objects in query builder

i am joining two tables with query builder. here is the sample
$events = DB::table('eventcalenders')
->select('eventcalenders.id','eventcalenders.event_name',)
->join('countries', 'eventcalenders.country_id', '=', 'countries.id')->get();
can i declare an object of eventcalender as e and select with object name like 'e.id','e.event_name'.?
Yes, after the query you need to loop through them since they are more than one item:
foreach($events as $e){
$name = $e->event_name;
}
If you want to select only the first one that meets your constrains then use .first().
$event = DB::table('eventcalenders')
->select('eventcalenders.id','eventcalenders.event_name',)
->join('countries', 'eventcalenders.country_id', '=', 'countries.id')->first();
$name = $event->event_name;
$events = DB::table('eventcalenders')
->select('eventcalenders.id','eventcalenders.event_name','countries.*')
->join('countries', 'eventcalenders.country_id', '=', 'countries.id')
->get();
Afetr getting results
foreach($events as $event)
{
echo $event->event_name;
echo $event->country_name; //your specific field
}

Query giving double result instead of single

I have two tables: products and current_product_attribute_values
I have tried a join query to filter them as per attribute selected by the user but when I try this with an additional condition it gives me 2 results instead of one it is including the first one which is not matching as per query:
select * from `products` inner join `current_product_attribute_values` on `products`.`id` = `current_product_attribute_values`.`product_id` where `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `product_name` LIKE ?
here is my laravel Controller code :
$all = Input::all();
$q = Input::get('search_text');
$att_val = Input::get('attribute_value');
$subcat = Input::get('subcat_id');
$subcat_name = DB::table('subcategories')->where('id', $subcat)->value('subcategory_name');
$brandname = DB::table('brands')->where('subcat_id', $subcat)->value('brand_name');
$brand_id = DB::table('brands')->where('subcat_id', $subcat)->value('id');
$product_count = DB::table('products')->where('brand_id', $brand_id)->count();
if ($q != "") {
// getting multiple same name params
$query = DB::table('products');
$query->join('current_product_attribute_values', 'products.id', '=', 'current_product_attribute_values.product_id');
$j = 0;
foreach ($all as $key => $values) {
//echo 'my current get key is : ' . urldecode($key). '<br>';
if ($key == $name[$j]) {
$query->where('current_product_attribute_values.attribute_id', '=', $att_id_value[$j]);
echo'<br>';
print_r($query->toSql());
echo'<br>';
//echo '<br> key matched and have some value : <br>';
//echo count($values);
if (count($values) >= 1) {
//echo '<br> it has array inside <br>';
foreach ($values as $val) {
// or waali query in same attribute
echo'<br>';
$query->orwhere('current_product_attribute_values.attribute_value_id', '=', $val);
print_r($query->toSql());
echo'<br>';
}
}
$j++;
}
}
$records = $query->toSql();
$query->where('product_name', 'LIKE', '%' . $q . '%');
$records = $query->toSql();
print_r($records);
$products = $query->paginate(10)->setPath('');
$pagination = $products->appends(array(
'q' => Input::get('q')
));
if (count($products) > 0) {
$filters = DB::table('product_attributes')->where('subcategory_id', $subcat)->get(['attribute_title']);
} else {
$filters = array();
}
$categories = categories::where('add_to_menu', 1)->with('subcategories')->with('brands')->get();
$categoryhome = categories::where('add_to_menu', 1)->with('subcategories')->get();
return view('searchfilter')
->with('productsdata', $products)
->with('filtersdata', $filters)
->with('categories', $categories)
->with('categorieshome', $categoryhome)
->with('subcat_name', $subcat_name)
->with('subcat_id', $subcat)
->with('brandname', $brandname)
->with('product_count', $product_count)
->with('querytext', $q);
}
return 'No Details found. Try to search again !';
its easier if you use raw sql as calling db select function. ex:
$query=DB::select("select * from `products` inner join `current_product_attribute_values` on `products`.`id` = `current_product_attribute_values`.`product_id` where `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `current_product_attribute_values`.`attribute_id` = ? or `current_product_attribute_values`.`attribute_value_id` = ? and `product_name` LIKE ?
");
indeed you can concat vars in raw sql if you need to, ex:
$queryBrands = "select id from brands where subcat_id =".$subcat;
//echo $queryBrands
$queryBrands = DB::select($queryBrands);
By looking at your tables, product table with id value 17 has two records in table current_product_attribute_values in column product_id (I assume this column is used as foreign key to product table).
With select *, you select all of the columns from both tables. So it would most likely cause your query to return multiple records.
My suggestions:
Only select the columns you need. Avoid using select * in the long run, i.e. select product.id, product.description, current_product_attribute_values.attribute_values ......
Make use of GROUP BY
Hope these helps.

$data = $query->row(); returns only one row

Im trying to list the results of my sql query (picking up all the movies from a category), but I cannot figure out how to get all the rows instead of only one.
Here's the code :
$this->load->database();
$sql = 'SELECT * FROM movies WHERE category = "'.$movies_category.'";';
$query = $this->db->query($sql);
$data = $query->row();
$this->response($data, 200);
I've tried :
while($row = mysql_fetch_assoc($query)){
$data = $query->row();
}
$this->response($data, 200);
And it doesn't work. Any suggestion ? Thank you !
$this->load->database();
$sql = 'SELECT * FROM movies WHERE category = "'.$movies_category.'";';
$query = $this->db->query($sql);
$data = $query->result();
To traverse the $data array:
foreach($data AS $row)
{
//to retrieve the data from each row.
$col1 = $row->col1;
$col2 = $row->col2;
}
Use result() instead of row(). result() will return an array of objects that are your results. Alternatively, you can useresult_array() which will resturn an array of arrays keyed according to your columns. Please refer to here for a better outline of the result() and row() methods.
Do you have a database configuration file? the load->database() requires it. Where is $movies_category coming from? This will let you iterate over your results.
$this->load->database();
$sql = 'SELECT * FROM movies WHERE category = "'.$movies_category.'";';
$query = $this->db->query($sql);
foreach ($query->result() as $row)
{
echo $row->column;
}
Where column corresponds with one of the values in the movies table.
I'm surprised nobody has mentioned the potential hazards of using variables (possibly user input) in your SQL. You should seriously consider using query bindings or the active record features of CodeIgniter to build safer queries.
Consider the following solution to your problem:
$this->load->database();
$sql = 'SELECT * FROM movies WHERE category = ?';
$query = $this->db->query($sql, array($movies_category));
// $data = $query->result(); // returns result as an array of objects
$data = $query->result_array(); // returns result as array
$this->response($data, 200);
I'm assuming this is for some sort of API? If so, consider using the result_array() method as it will probably be better suited for your needed output, and also really easy to convert into JSON:
$json_data = json_encode($data);
Hope that helps,
Cheers.
For your question row() return only one value its good for checking in ID and if you want get all the rows use result_array() or simple result()
You can try this code....
Model:
function get_movies($movies_category){
$this->db->where("category",$movies_category);
$query = $this->db->get("movies");
return $query->result_array();
}
Controller:
$this->data['movies'] = $this->'name of model'->get_movies('here is the movie categories');
View:
foreach($movies as $m){
print_r($m);
}
exit();
Note you can directly add the code in function in model to controller add this in your controller if you want directly...
$this->data['movies] = $this->db->get('movies')->result_array();

getting the id from a table in database

i have 3 tables city, information and state. In my code i've shown the different cites under different state. what i want to do is to get the seperate ids of the cities so that i can run some queries in my 'information' table.
My model is given below:
function get_status(){
$states = $this->db->get('state');
$like = array();
$status = array();
foreach ($states->result() as $state){
$cities = $this->db->get_where('city', array('state_id'=> $state->id));
$like=$cities->result();
$status=$like[0]->city_id;
}
echo $status;
}
but when i run the code i only get the last id of the last city stored under the last state in the the table. for example the state 3 has city that has id 3. i'm only getting this id. but i want all the ids of the cities like- 1,2,3.
i'm using Codeigniter framework.
Thanks in advance
$like - it`s an array.
[0] - the first element of an array.
echo $like[0]->city_id;
I haven`t tested it. (In one iteration -> it takes all the cities from that ID)
function get_status(){
$states = $this->db->get('state');
$like = array();
$status = array();
foreach ($states->result() as $state){
$cities = $this->db->get_where('city', array('state_id'=> $state->id));
foreach ($cities->result() as &$v){
echo $v->city_id."<br/>";
}
echo "......<br/>";
}
}

City name query

Am a newbie to Lucene an working on a city search API using Lucene.
If user types in san francisco as search input, then it should give cities with exact match only and not San Jose /San Diego,etc.
How should i index city names in Lucene?and which Lucene analyzer and query class do i need to use?
Index your content with StandardAnalyzer. And then use PhraseQuery to search. For this, simply use the query string as "san francisco" with double quotes.
<?php
if(isset($_POST['submit']) && $_POST['submit']=='submit' ){
$city = $_POST['city'];
$query = "SELECT * FROM libreary WHERE city LIKE'".$city."'";
$row = mysqli_query($con,$query);
$result = mysqli_num_rows($row);
if($result>0){
while($row1 = mysqli_fetch_array($row)){
print_r($row1);
}
}
$respon['Response'] = $response;
print_r(json_encode($respon));
}
?>