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')
Related
I have 2 tables i.e. users and user_managers, with the following structure and data:
users
id
name
employee_number
1
Employee One
ACB1234
2
Employee Two
XYZ1234
3
Employee Three
EFG1234
4
Employee Four
HIJ1234
user_managers
id
user_id
manager_of_user_id
1
1
2
2
2
3
3
4
1
4
5
4
I want a recursive function to get the complete chain of the managers. For example, if query for user_id = 4, I should get the following result:
result
user_id
name
employee_id
comments
1
Employee One
ABC1234
user managed by 4
2
Employee Two
XYZ1234
user managed by 1
3
Employee Three
EFG1234
managd by user 2
5
Employee Five
JKL1234
manager of user 4
The table above is just for the clarification, I am looking for a recursive function to get the above result.
I have tried the below solution but it is working for only 1 level.
public static function getCompleteChain(User $user)
{
$managerUsers = $user->managers;
foreach ($managerUsers as $manager) {
$manager->user = User::where('employee_id', $manager->manager_of_user_id)->first();
self::getCompleteChain($manager->user);
}
return $managerUsers;
}
Thanks in advance.
I have two tables
field_values (with some data)
id field_id value label sort
1 1 1 Men 1
2 1 2 Women 2
3 2 3 Relationship 1
4 2 4 Chat 2
5 2 5 Friendship 3
user_interests (with some data)
user_id field_id value_id
1 1 1
1 2 4
1 2 5
I am trying to write a query where I will get user with id 1 and have field_id 2 and to be able to echo in my blade value_id 4 and 5 but not to echo those ids but to echo value of 'label' column that corresponds to value_id form user_interests table in this case 4,5 thus Chat, Friendship from field_values table in this example. Here is what I tried but I get array of six elements which are Relationship, Chat, Friendship x2. Any help is appreciated.
query:
public static function queryFunction($userId)
{
$results = DB::table('user_interests as uin')
->select(DB::raw("
fv.*,
uin.field_id, uin.value_id
"))
->join('field_values as fv', 'fv.field_id', '=', 'uin.field_id')
->where('uin.field_id', 2)
->where('uin.user_id', $userId)
->get();
dd($results);
return $results;
}
What about 2 clear steps, without join:
$user_interests = DB::table('user_interests')->select('value_id')->where('field_id', 2)->where('user_id', $userId)->get();
From this take values as array ($user_interests_values)
and than
$results = DB::table('field_values')->whereIn('value', $user_interests_values)->get();
I have three tables
1-rests
2-amenity_rest
3-amenities
rests
id name
1 rest1
2 rest2
3 rest3
amenities
id name
1 amenity1
2 amenity2
3 amenity3
amenity_rest
rest_id amenity_id
1 1
1 3
2 2
3 1
I would like to send a List of amenities like [1,3]
and it should return the rest that its id=1
and if I send array [1,2,3] it should return no result
How would such a query look alike?
You can construct the query as:
select ar.rest_id
from amenity_rest ar
where ar.amenity_id in (1, 2, 3)
group by ar.rest_id
having count(*) = 3; -- "3" = size of list
Your controller should have a function like this:
function retrieveData(Request $request){
$data = Amenities_rest::whereIn('amenity_id', $request->amenities)
->groupBy('rest_id')
->havingRaw('COUNT (*) = ' . count($request->amenities))
->get();
return $data
}
That should do it. I hope it helps.
Table 1 - User:
ID Name
1 Jonh
2 Mark
3 King
Table 2 - Book:
ID user_idstatus ...
1 1 1 ...
2 1 1 ...
3 1 1 ...
4 2 1 ...
5 1 0 ...
6 1 0 ...
Code:
$query = User::find();
$query->joinWith('books');
$query->select(['user.*', 'COUNT(book.id) AS booksCount']);
$query->andWhere(['book.status' => 1]); // Problem Here!
$query->groupBy(['user.id']);
$query->orderBy(['booksCount' => SORT_DESC]);
Problem:
The query is working properly, but it's not returning the user with id = 3.
If I remove the line $query->andWhere(['book.status' => 1]); it works fine and return all users.
What should I change to list all users, even those who do not have a related book with status = 1?
I found the answer:
$query = User::find();
$query->joinWith(['books' => function ($subquery) {
$subquery->onCondition(['book.status' => 1]);
}]);
$query->select(['user.*', 'COUNT(book.id) AS booksCount']);
$query->groupBy(['user.id']);
$query->orderBy(['booksCount' => SORT_DESC]);
Instead of using COUNT(book.id), if the status of the book is either 0 or 1, you can use SUM(book.status) to get the number of books the user has. Then you can remove your WHERE book.status = 1 clause, and it will return all the users with the number of books they have, even in user 3's case where they have 0 books.
The Problem
The real problem is in your where clause. Because WHERE is processed before grouping and user 3 doesn't have any rows where book.status = 1, then the user has no rows which are included in the base query. Therefor the user isn't present during/after the grouping.
If you want a pretty good idea of a catch-all case where you can count rows based on a condition, using COUNT(CASE WHEN book.status IS NULL THEN NULL ELSE NULLIF(0,book.status) END) will also give you the result you're looking for. Because COUNT() will not count rows where the expression is NULL, this would allow the book.status to be -1, 1, 2, and any other number as long as it isn't 0 (or NULL in user 3's case), and still be included in the count.
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.