codeigniter, join table properties overrides other properties - php

I'm working on a project using codeigniter 3 and I have a following query
$this->db->select("*");
$this->db->from("questions");
$this->db->join('users', 'users.id = questions.user_id');
$this->db->where('article_id', $articleId);
$this->db->order_by('questions.id', 'DESC');
$query = $this->db->get();
return $query->result();
// query
// SELECT * FROM `questions` JOIN `users` ON `users`.`id` = `questions`.`user_id` WHERE `article_id` = 18 ORDER BY `questions`.`id` DESC
Currently, the id property from users table overrides the questions id one. The question's id is crucial.
I worry, I will have to write a custom query, which I am not really good at.

Try to do this as follow:
$this->db->select("*, questions.id as question_id");
It's obvious that properties with the same name will be overriden. That's why you should assign to them 'unique' names in select statement.

You can specifically mention the ids with alies like -
$this->db->select("questions.id as question_id, users.id as user_id, questions.*, users.*");
$this->db->from("questions");
$this->db->join('users', 'users.id = questions.user_id');
$this->db->where('article_id', $articleId);
$this->db->order_by('questions.id', 'DESC');
$query = $this->db->get();
return $query->result();
This will give you specific columns named with question_id, user_id, questions table's all columns, users table's all columns
Or another better solution to use specific column names in select with alies if required.

Related

sql command does not execute properly

I have a two tables in my database instructors and courses . I want to join them and for this reason wrote this code
$this->db->join('instructors', 'instructors.id = courses.instructor_id', 'left');
$query = $this->db->get_where('courses', array('courses_slug' => $slug));
return $query->row_array();
This code means:
SELECT * FROM `courses` LEFT JOIN `instructors` ON `instructors`.`id` = `courses`.`instructor_id` WHERE `courses_slug` = 'abituriyent-hazirligi'
But when I write this code to check:
$data['courses'] = $this->popular_courses_model->get_popular_courses($slug);
echo $data['courses']['id'];
die();
It writes the instructors id, not id of the course. Where can be the problem? Thanks in advance.
You are joining two table with columns of the same name ('id'). You need to be specific in your select for the columns and rename ('AS') if necessary.
select courses.id as course_id, instructor.id as instructor_id, ...
When using joins you should explicitly call out what columns you want returned like:
$select = "c.id, c.name, c.instructor_id, i.name instructor_name";
return $this->db->select($select)
//equivalent to "instructors as i"
->join('instructors i', 'i.id = c.instructor_id', 'left')
->where('c.courses_slug', $slug)
//equivalent to "courses as c"
->get('courses c')->row_array();

get user with most articles and its amount with active record or query

I want to get the user that wrote the most articles. I do so fine in two ways with ActiveRecord like the following:
$table = Articles::find()
->select('articles.*, COUNT(*) AS cnt')
->with('user','userDetails')
->groupBy('articles.user_id')
->orderBy(('cnt DESC'))
->limit(10)
->offset($offset)
->all();
and with a query like the following:
$query = (new Query())
->select('articles.user_id, COUNT(*) AS num_articles')
->from('articles')
->join('LEFT JOIN', 'user_details', 'user_details.user_id = articles.user_id')
->groupBy('articles.user_id')
->orderBy('num_articles DESC')
->limit(10)
->offset($offset)
->all();
The problem is that the ActiveRecord gives me further needed informations userDetails that I need. But I do not get the amount of articles of user that should be on cnt
With the Query I get the user_id and the amount of articles. But I do not get it working by joining with userDetails. All of these does not work: LEFT JOIN, RIGHT JOIN, INNER JOIN.
I am interested in resolving both for learning, but for concrete I need help with the ActiveRecord problem.
Okay well I solved it for the ActiveRecord. The ActiveRecords needs a public $var; in the Model. So to get the amount you have to add the mentioned public... to your Model so that in my case:
public $cnt; extends the ActiveRecord of Articles
now I can access it with the given Request in my Question. But this just solves the first point. I am still interested in the second way for more complex Queries.
I dont have much idea about active record but I think the below is something what you are looking for
select * from user_details where user_id in
(select A.user from
(select user_id as user, COUNT(*) AS num_articles
from articles group by user_id order by num_articles desc LIMIT 10)A
);
for second point you should include required column from joined table to select statement:
$query = (new Query())
->select('articles.user_id, COUNT(*) AS num_articles, user_details.username as username')
->from('articles')
->join('LEFT JOIN', 'user_details', 'user_details.user_id = articles.user_id')
->groupBy('articles.user_id')
->orderBy('num_articles DESC')
->limit(10)
->offset($offset)
->all();

Query for getting values from multiple tables

I have a table video with fields videoid, genre(int-foreign key), language(int-foreign key) etc. I want to get the value of genre from genre table and language from movie_languages table.
The structure of tables are given below:
video
genre
movie_languages
How can I join these 3 tables to get the language and genre related to each videos in video table. Also when user didn't select genre/language in the form, value 0 will be inserted to the table. Will this affect the query. I am using codeingiter and I tried with the following query and is not working.
$this->db->select('video.*,movie_languages.language,genre.genre');
$this->db->join('genre', 'video.genre = genre.id');
$this->db->join('movie_languages', 'video.language = movie_languages.id');
$query = $this->db->get();
Please help me.
Thanks in advance.
It will be, you need a left join in this case
Try this
$query = $this->db
->select('v.*,ml.language,g.genre')
->from('video as v')
->join('movie_languages AS ml', 'v.language = ml.id', 'left outer')
->join('genre AS g', 'v.genre = g.id', 'left outer')
->get();
try this
$this->db->select('video.*,movie_languages.language,genre.genre')
->from('video')
->join('genre', 'video.genre = genre.id')
->join('movie_languages', 'video.language = movie_languages.id');
$query = $this->db->get();

Many to many database association in codeigniter

I am creating a sort of card collection programme with codeigniter and ion_auth for authentication. A user should be able to add a card to his collection.
So i have a users table and a cards table and a junction/bridge table.
users
ID
NAME
and
cards
ID
NAME
and
users_cards
ID
USER_ID
CARD_ID
I want to accomplish a SELECT statement that retrieves the cards from a users through user_cards.
$this->db->select('*');
$this->db->from('cards');
$this->db->join('users_cards', 'users.id = users_cards.user_id', 'inner');
$this->db->join('users', 'users_cards.user_id = users.id', 'inner');
$query = $this->db->get();
return $query->result_array();
I cant seem to get a grasp at the concept of these joins. Can someone please help me?
Looks like the join statement is missing the reference to the 'cards' table.
$this->db->select('*');
$this->db->from('users_cards');
$this->db->join('users', 'users.id = users_cards.user_id', 'inner');
$this->db->join('cards', 'cards.id = users_cards.card_id', 'inner');
$query = $this->db->get();
return $query->result_array();
The idea is that you're trying to get a relationship going between users_cards and the other two tables by referencing their relevant ids
Since you didn't joined users table you can't join based on the users.id reference. So you need to change
$this->db->join('users_cards', 'users.id = users_cards.user_id', 'inner');
to
$this->db->join('users_cards', 'cards.id = users_cards.card_id', 'inner');

CodeIgniter PHP - How to choose which ID to select in a join while using "select *"

Basically, I've got this coding convention that any primary key which is an ID, I will call the column name "id". So here comes my problem. I'm joining two tables and I'm getting the ID of the second table instead of the first table. I know if I use select "artists.id, ..." it will work, but I want to know if there's a fix with using "select *" which would be better for future expansion (new colums will come ...).
Here's my model:
$this->db->select('*');
$this->db->from('artists');
$this->db->join('categories', 'artists.category_id = categories.id');
$this->db->where('id', $id);
$this->db->limit(1);
With Print_R I can see I'm getting all columns (but only 1 id, which is from the categories table instead of artists table) without any table prefix.
You should qualify your columns with a table alias
$this->db->select('a.id as artist_id, c.id as category_id, a.column2,c.column3');
$this->db->from('artists a');
$this->db->join('categories c', 'a.category_id = c.categories.id');
$this->db->where('a.id', $id);
$this->db->limit(1);
If you want to continue using SELECT *
$this->db->select('a.*, c.*, a.id as artist_id, c.id as category_id');
$this->db->from('artists a');
$this->db->join('categories c', 'a.category_id = c.categories.id');
$this->db->where('a.id', $id);
$this->db->limit(1);
Keep in mind, that the LAST duplicate column will be returned. So, a.*,c.* will return c.id as id and c.*,a.* will return a.id as id.
I think to save you trouble and for the future, always use the table in front of the column name.
There is no logic here, when you look for * it means all fields, in Oracle for example you will get all fields with the table in front, i guess in MySQL it doesn't, but if i were you, i would not risk it.

Categories