I have written a model code where i am joining two tables, and returning my results.
From the below table structure my model code is showing only 2 question count, skipping the last question, After little research i found the reason why it is not counting my third question, it is because it does not have any answer in my answer table.
I want, if no answer then it should show count=0 for the particular question, How can to solve this issue?
Table structure
question
-----------
question_id PK Auto_Incr
question varchar...
votes int
answer
------------
answer_id PK Auto_icre
question_id FK refrences question
content longtext
Table Data structure data:
question
-----------
question_id question votes
1 what's name? 0
2 where you? 3
3 blah blah 9
answer
----------
answer_id question_id content
4 2 India
5 2 Nepal
6 2 Pakistan
7 1 Mr Osama Binladan
Model
public function fetch_allquestions($limit, $start)
{
$this->load->database();
$this->db->limit($limit, $start);
$this->db->from('question');
$select =array(
'question.*',
'userdetails.*',
'COUNT(answer.answer_id) AS `Answers`'
);
$this->db->select($select);
$this->db->join('answer','answer.question_id = question.question_id');
$this->db->join('userdetails','userdetails.user_id = question.user_id');
$query = $this->db->get();
print_r("Number of rows=".$query->num_rows());//showing only One, out of 26 rows
if ($query->num_rows() > 0)
{
foreach ($query->result() as $row)
{
$data[] = $row;
}
return $data;
}
else
{
return false;
}
}
You should use LEFT join
$this->db->join('answer','answer.question_id = question.question_id','LEFT');
What you need is a LEFT JOIN, which basically means that if there is a row in the table mentioned first exists, a corresponding row in the second table mentioned is not required. In your case, if there's a question, it will be returned even if there is no matching answer.
To do a left join in codeigniter, you can just pass 'left' as a third parameter to your call to join;
$this->db->join('answer','answer.question_id = question.question_id', 'left');
More info on the join call is available at the CodeIgniter docs.
Related
I have three tables Beneficiary, Questions, Responses..Beneficiary
Benficiary
id name
1 user1
2 user2
3 user3
Questions
id question type
1 what is your hobby hobby
2 address contact
3 phone contact
..questions upto 500 and i need to select according to its type
Response
id beneficiary_id question_id response
1 1 1 football
2 1 3 5354353
3 2 1 basketball
4 3 2 cityname
5 3 3 432423
Beneficiary table and Question table are static but response table joins both of them. I tried to do this from laravel query but it gives me only responses
sql query
select response,questions.question, beneficiarys.name
from responses RIGHT join (questions,beneficiarys)
on beneficiarys.id = responses.beneficiary_id && questions.id = responses.question_id
where questions.sheet_type = 'SCDS' OR questions.sheet_type = 'SMM'
laravel query
$beneficiaries = Beneficiary::with('quests','response')->whereHas('response', function ($query)use($sheet_type) {
$query->where('beneficiary_id', '>', 0);
})
->whereHas('quests',function($query)use($sheet_type){
$query->where('questions.sheet_type','=',$sheet_type);
$query->orWhere('questions.sheet_type','=','SCDS');
})
->where('updated_at','>=',!empty($this->request->from_date)?$this->request->from_date:$from)->where('updated_at','<=',!empty($this->request->to_date)?$this->request->to_date:$date)->get();
Beneficiary Model
public function response()
{
return $this->hasMany('App\Model\Response');
}
public function quests(){
return $this->belongsToMany('App\Model\Question', 'responses','beneficiary_id','question_id');
}
Question Model
public function response(){
return $this->hasMany('App\Model\Response');
}
public function bens(){
return $this->belongsToMany('App\Model\Bebeficiary', 'responses','question_id','beneficiary_id');
}
Response Model
public function beneficiary(){
return $this->belongsTo('App\Model\Beneficiary', 'beneficiary_id');
}
public function question(){
return $this->belongsTo('App\Model\Question', 'question_id');
}
I need all the question according to its type(type is selected by user from view) and i need output like this
beneficary hobby address phono ....
user1 football null 4244 ....
user2 basketball null null ....
is there any way to achieve it with sql or laravel query*
this is the mysql select, maybe is a better way to it but this work
SELECT b.name,hobby.response as hobby,address.response as addres,phone.response as
phone FROM beneficiary as b
left join (select * from response where question_id=1 ) as hobby
on hobby.beneficiary_id = b.id
left join (select * from response where question_id=2 ) as address
on address.beneficiary_id = b.id
left join (select * from response where question_id=3 ) as phone
on phone.beneficiary_id = b.id
You Will get result from this query. Laravel Support customization as well.
$sSQL = "SELECT * FROM RESPONSE
INNER JOIN QUESTION ON QUESTION.id=RESPONSE.QUESTION_id
INNER JOIN BENEFICIARY ON BENEFICIARY.id=RESPONSE.BENEFICIARY_id";
DB::query($sSQL);
Try
$res = DB::table('responses')
->join('questions','responses.question_id','=','questions.id')
->join('beneficiarys','responses.beneficiary_id','=','beneficiarys.id')
->select('responses.*','questions.question','beneficiarys.name')
->where('questions.sheet_type', '=','SCDS')
->orWhere('questions.sheet_type','=','SMM')
->get();
Use the result as
foreach($res as $res)
{
echo $res->name;
}
If you want to do it Eloquent way you could try using whereHas on your nested relationships. Try something like :
Beneficiary::with('response.question')->whereHas('response.question')
For more references try this link Eloquent with nested relationships
The documentation only mentions these parameters.
$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);
Is the above absolute? or is there more details hidden somewhere in the codeigniter userguide?
I would like to know how to only return rows of a specific column.
For example, on a Person table. I only wanted the name of the row in person table with the person_id of 1. Or for example, on children table, i want to get only the rows for child_name of parent_id = 1.
$this->db->get_where('person', array('person_id' => 1))->result_array();
Say Children table has 4 columns.
Person_id Child_id Child_Name and Child_age
So 1 person id can have as many children. Say the values are.
1 1 john 4
1 2 peter 3
1 3 michael 7
2 4 noah 10
So i only want the name of the children of person_id = 1.
You can do method chaining as such:
public function get() {
return $this->db->select('person_name')
->get_where('person', array('person_id' => 1))
->result_array();
}
Or just simply
public function get() {
$this->db->select('person_name');
return $this->db->get_where('person', array('person_id' => 1))->result_array();
}
But the get_where or similar function of CI query builder don't have in-built select statements other than $this->db->select('somename')
I'm having a problem at the moment where I have a column called rating in the links table and there is definitely values other than 0 within the column but 0 is the only value which is returned foreach link. When I do a simple get for that column it then shows all the other values but not when I do an SQL Join.
I know the problem is my joining of the tables but I'm unsure how I would go about joining these specific tables.
Database Table Structure
The rating column is the one which is causing me problems.
'links' id | title | url | user_id | list_id | rating | weight | date_created
'list' id | list_title | list_description | user_id | rating | views | date_created
'link_ratings' id | user_id | link_id | rated | date_created
Model:
public function get_latest(){
$this->db->limit(100);
$this->db->order_by('links.date_created', 'DESC');
$this->db->select('*');
$this->db->select('links.id as current_link_id');
$this->db->from('links');
$this->db->join('list', 'links.list_id = list.id');
$this->db->join('users', 'links.user_id = users.id');
$this->db->join('link_ratings', 'links.id = link_ratings.link_id','left');
$get_latest = $this->db->get();
return $get_latest;
}
Any Help is appreciated.
You should try this:
function get_latest(){
$this->db->select('list.*, users.*, links.id as current_link_id');
$this->db->from('links');
$this->db->join('list', 'links.list_id = list.id');
$this->db->join('users', 'links.user_id = users.id');
$this->db->join('link_ratings', 'links.id = link_ratings.link_id','left');
$this->db->order_by('links.date_created', 'DESC');
$this->db->limit(100);
$get_latest = $this->db->get()->result_array(); #fetch all rows here
echo "<pre>";print_r( $get_latest );die; #print all rows and see if its fetching ratings corrctly or not.
echo $this->db->last_query();die; #check the query generated
return $get_latest;
}
The reason will be purely logical, in that the join will be causing no results to be returned because there are no results. I've fallen into this many times.
I am not able to diagnose your particular problem but when faced with issues like this I:
1- turn on the CI profiler
2- var_dump the array so you can see what's going on
3- write a traditional SQL query and run it in PHPMyAdmin
One, or a combination of all three, will enable you to diagnose.
Actually found a lot of question like this before posting but doesn't find one related with "Codeigniter" so I don't know how to implement those answer with codeigniter.
My meta_key table
key_id | key_name | key_parent
------------------------------
.....1..firstname........1
.....2..lastname.........1
My users_meta table
meta_id | meta_user_id | meta_key_id |meta_value |
--------------------------------------------------
1.........1..............1............chuck......
When I run this query
$this->db->select("*");
$this->db->from("meta_key");
$this->db->join("users_meta", "users_meta.meta_key_id=meta_key.key_id","left");
$this->db->where('users_meta.meta_user_id', '1');
$query=$this->db->get();
return $query;
It always return me single rows ( that is the firstname rows )
Instead of "left" join I tried every option ( Options are: left, right, outer, inner, left outer, and right outer ) from the codeigniter reference page but it still return single rows.
How can I make it to return the "surname" rows as well ?
As you commented that following code works for you so here it is as answer
//just guess and try
$this->db->where('users_meta.meta_user_id = 1 OR users_meta.meta_key_id IS NULL');
I want to pull from my database records corresponding to parent_id, like this:
function getChildren($id, $parent_id) {
$q = $this->db->select('id, name, slug, plat');
$q = $this->db->from('games');
$q = $this->db->where('parent_id',$id);
$q = $this->db->or_where('id',$parent_id);
$q = $this->db->get();
return $q->result_array();
}
It - if it's a children game - get parent_id and search for a game with such id and for other games that has parent_id same as this one. If it's the parent game, it only looks for games with parent_id same as it's id.
The problem is... it's not always working. I have four games in db:
id | parent_id | title
15 | 0 | Abe
19 | 15 | Abe
20 | 0 | RE2
21 | 20 | RE2 DS
First two works, last two - only children (id = 21) shows parent.
You likely could not do that with a relation database. RDBMS are not intended to manage any form of trees.
You can in some simple case, like one-level hierarchy, but as soon as it becomes more complex, it's getting messier and messier.
Keeping your structure, you have to make ONE JOIN per LEVEL, and that means knowing the depth in advance.
A solution to store trees in database is called Nested Tree, it basically stores interval for in each rows, but it is a bit complex to implement by yourself.
Take a look at Wikipedia explanation. There are however library which allows you to programmatically abstract such operations.
Use this query
select
*
from games as g
where parent_id = 0
union all
select
l.*
from games r
left join (select * from games) as l on r.id = t.id
where
r.parent_id != 0
Just after posting my problem, I tried another solution. Funny, I sit with this for more than an hour and after wasting your time, I came with the solution ;)
Anyway, here it is:
function getChildren($id, $parent_id) {
$q = $this->db->select('id, name, slug, plat');
$q = $this->db->from('games');
$q = $this->db->where('parent_id',$id);
$q = $this->db->or_where('id',$parent_id);
$q = $this->db->or_where('parent_id',$parent_id);
$q = $this->db->where('id !=', $id);
$q = $this->db->get();
return $q->result_array();
}