codeigniter join same table multiple values - php

i need some codeigniter 3 help from you friends. its like 10 years ago when i did some more complex querys and my noobish JOIN-trys just gave me errors and questionmarks for hours.
lets say i have a mysql table covers
id, text, bgcolor_id, color_id
example : 1, "nice headline", 55, 88
and a table colors
id, value, name
example : 55, #FF0000, "red"
example : 88, #000000, "black"
how to "link" based on bgcolor_id, color_id in table covers
cover.bgcolor_id ->
color.value AS bgcolorvalue
color.name AS bgcolorname
cover.color_id ->
color.value AS colorvalue
color.name AS colorname
my codeigniter model
public function list(){
$query = $this->db->query('SELECT * FROM covers ORDER BY id DESC');
return $query->result_array();
}
public function get($id){
$query = $this->db->query('SELECT * FROM covers WHERE id = ' . $id);
return $query->row();
}

Join twice your colors table
select c.*,c1.name bgcolorname,
c1.value bgcolorvalue,
c2.name colorname,
c2.value colorvalue
from covers c
join colors c1 on c.bgcolor_id = c1.id
join colors c2 on c.color_id = c2.id
DEMO

I strongly recommend you to use the query builder Reference
You could to something like.
$cv = 'covers';
$cl1 = 'colors';
$cl2 = 'colors';
$get = array(
$cv.'.id',
$cv.'.text',
$cv.'.bgcolor_id',
$cv.'.color_id',
$cl1.'.value as bgcolorvalue',
$cl1.'.name as bgcolorname',
$cl1.'.value as colorvalue',
$cl1.'.name as colorname'
);
$this->db->select($get);
$this->db->from($cv);
$this->db->where($cv.'.id', 1);
$this->db->join($cl1, $cv.'.bgcolor_id = ' . $cl1.'.id');
$this->db->join($cl2, $cv.'.color_id = ' . $cl2.'.id');
$result = $this->db->get()->result();
let me know if this works

As i have understood your question right then you want to join on colors table twice for bgcolor_id and color_id, so here i am providing solution for your question let me know if it works or something wrong with the solutuion, thanks.
public function list(){
$query = $this->db->select("covers.*, bg.value AS bgcolorvalue bg.name AS
bgcolorname, colors.value AS colorvalue
colors.name AS colorname")
->join("colors", "colors.id = covers.color_id", "left")
->join("colors as bg", "bg.id = covers.bgcolor_id", "left")
->get("covers")->result();
return $query->result_array();
}

Related

Mysql get all rows but join if possible [duplicate]

I have 3 mysql tables.
Table 1 user
id | name
Table 2 emails
id | email
Table 3 user_email
user_id | email_id
I have no experience in query multi tables.
Using codeigniter active record, i want to find out the user email address based on the user id, pls advise if the below code is correct ?
$CI->db->select('email');
$CI->db->from('emails');
$CI->db->where('id', $userid);
$CI->db->join('user_email', 'user_email.user_id = emails.id', 'left');
$query = $CI->db->get();
You have wrong where clause you need to compare user_id from your table ,you are comparing the id of email to the provided $user_id
$CI->db->select('email');
$CI->db->from('emails');
$CI->db->where('user_id', $userid);
$CI->db->join('user_email', 'user_email.user_id = emails.id', 'left');
$query = $CI->db->get();
A more useful way is to give aliases to your tables so the tables with same columns will not have any confusion
$CI->db->select('e.email');
$CI->db->from('emails e');
$CI->db->join('user_email ue', 'ue.user_id = e.id', 'left');
$CI->db->where('ue.user_id', $userid);
$query = $CI->db->get();
#m khalid 's answer is correct but I have created a dynamic function to achieve join with multiple tables. Check this out.
function join_records($table, $joins, $where = false, $select = '*', $orderBy = false, $direction = 'DESC'){
$CI->select($select);
$CI->from($table);
foreach($joins as $join){
$CI->join($join[0], $join[1], $join[2]);
}
if($where) $CI->where($where);
if($orderBy) $CI->order_by($orderBy, $direction);
$query = $CI->get();
return $query->result_array();
}
Applying your question to this.
$table = 'emails';
$joins[0][0] = 'user_email';
$joins[0][1] = 'user_email.user_id = emails.id';
$joins[0][2] = 'left';
$where['user_id'] = $userid;
You may add more join like $join1[0]..
If you need to select some specific column you can define in following manner
$select = 'table1.column1, table1.column2, table2.column1, table2.column2'
Or if you want all the columns put a *
$this->join_records($table, $joins, $where, $select);
You may also find it here.

Multilingual databases using Codeigniter

I have applied the method Additional Translation Approach in the database design.
With such structure of the tables, the code becomes more complex for per query.
My PHP code in models:
<?php
// SHOW ALL RECORDS
$this->db->select('m.id, m.title, m.content');
$table = 'blog';
if (MULTILINGUAL) {
$this->db->from($table.' AS m');
$this->db->select('t.title, t.content');
$this->db->join($table.'_translation AS t', 'm.id = t.parent_id', 'left');
$this->db->where('t.language_id', LANGUAGE);
$query = $this->db->get();
} else $query = $this->db->get($table.' AS m');
?>
So I want to change it's code...
When MULTILINGUAL is true, and with per query has column fields is title, content,...
$table = 'blog';
$this->db->select('id, title, content');
$query = $this->db->get($table);
it will automatically use the method JOIN with a table have suffix _translation (as my code above).
Otherwise, queries should be run as a normal query.
How can I do modified db class but don't affects core system of Codeigniter?
PHP code (using Codeigniter):
// Query 1:
$this->db->select('id, title, content');
$query = $this->db->get('blog');
// Query 2:
$this->db->select('id, title, content');
$this->db->where('id', 1);
$query = $this->db->get('blog');
Produces $this->db->last_query():
if (MULTILINGUAL) {
// Query 1:
// SELECT t.title, t.content FROM blog AS m LEFT JOIN blog_translation AS t ON m.id = t.parent_id WHERE t.language_id = 1
// Query 2:
// SELECT t.title, t.content FROM blog AS m LEFT JOIN blog_translation AS t ON m.id = t.parent_id WHERE t.language_id = 1 WHERE m.id = 1
else {
// Query 1:
// SELECT title, content FROM blog
// Query 2:
// SELECT title, content FROM blog WHERE id = 1
}
I want it to be completely automatic.
I think that could change the db class to solve this problem, but direct intervention into the core system is unstable (within core update)...
I truly appreciate your help in resolving my problem!
This might help you to work around I don't know how you were using that config file but can achieve that functionality as
function your_function($multilingual = false) {
$table = 'blog';
if ($multilingual === true) {
$this->db->select('t.title, t.content');
$this->db->join($table . '_translation AS t', 'm.id = t.parent_id', 'left');
$this->db->where('t.language_id', LANGUAGE);
$query = $this->db->get($table . ' AS m')->result_array();
} else {
$this->db->select('m.id, m.title, m.content');
$query = $this->db->get($table . ' AS m')->result_array();
}
return $query;
}
You could create a view and just call : $this->db->where('t.language_id', LANGUAGE); , but I don't know really if this is a better solution.

getting three records in descending order of each category using codeigniter

I've two categories and I want to fetch three records of each category later I found this link UNION query with codeigniter's active record pattern after this I change my DB_Active_rec file and add this code also
var $unions = array();
public function union_push($table = '') {
if ($table != '') {
$this->_track_aliases($table);
$this->from($table);
}
$sql = $this->_compile_select();
array_push($this->unions, $sql);
$this->_reset_select();
}
public function union_flush() {
$this->unions = array();
}
public function union() {
$sql = '(' . implode(') union (', $this->unions) . ')';
$result = $this->query($sql);
$this->union_flush();
return $result;
}
public function union_all() {
$sql = '(' . implode(') union all (', $this->unions) . ')';
$result = $this->query($sql);
$this->union_flush();
return $result;
}
and then I create codeigniter's function based query like this
$this->db->select("*");
$this->db->from("media m");
$this->db->join("category c", "m.category_id=c.id", "INNER");
$this->db->order_by("m.media_files", "DESC");
$this->db->limit(3);
$this->db->union_push();
$this->db->select("*");
$this->db->from("media m");
$this->db->join("category c", "m.category_id=c.id", "INNER");
$this->db->order_by("m.media_files", "DESC");
$this->db->limit(3);
$this->db->union_push();
$getMedia = $this->db->union_all();
create this
(SELECT * FROM media m INNER JOIN category c ON
m.category_id = c.id ORDER BY m.media_files DESC LIMIT 3)
UNION ALL
(SELECT * FROM media m INNER JOIN category c ON
m.category_id = c.id ORDER BY m.media_files DESC LIMIT 3)
Now it is fetching records but not properly I want to use only query, it showing six records first query fetch 3 records and second query fetch three records now records are duplicate I check the id of records it is 6,5,4 and again 6,5,4. It can be done also by PHP but I want to use query. Thanks in advance
I dont know code-igniter, but basicly you want it to do the union first and then apply the order by over the whole set. This would require a subquery. It should result in the following SQL query:
select * from
((SELECT * FROM media m INNER JOIN category c ON m.category_id = c.id )
UNION ALL
(SELECT * FROM media m INNER JOIN category c ON m.category_id = c.id)) T
ORDER BY m.media_files DESC LIMIT 3
Hope it helps you some.

codeigniter active record left join

I have 3 mysql tables.
Table 1 user
id | name
Table 2 emails
id | email
Table 3 user_email
user_id | email_id
I have no experience in query multi tables.
Using codeigniter active record, i want to find out the user email address based on the user id, pls advise if the below code is correct ?
$CI->db->select('email');
$CI->db->from('emails');
$CI->db->where('id', $userid);
$CI->db->join('user_email', 'user_email.user_id = emails.id', 'left');
$query = $CI->db->get();
You have wrong where clause you need to compare user_id from your table ,you are comparing the id of email to the provided $user_id
$CI->db->select('email');
$CI->db->from('emails');
$CI->db->where('user_id', $userid);
$CI->db->join('user_email', 'user_email.user_id = emails.id', 'left');
$query = $CI->db->get();
A more useful way is to give aliases to your tables so the tables with same columns will not have any confusion
$CI->db->select('e.email');
$CI->db->from('emails e');
$CI->db->join('user_email ue', 'ue.user_id = e.id', 'left');
$CI->db->where('ue.user_id', $userid);
$query = $CI->db->get();
#m khalid 's answer is correct but I have created a dynamic function to achieve join with multiple tables. Check this out.
function join_records($table, $joins, $where = false, $select = '*', $orderBy = false, $direction = 'DESC'){
$CI->select($select);
$CI->from($table);
foreach($joins as $join){
$CI->join($join[0], $join[1], $join[2]);
}
if($where) $CI->where($where);
if($orderBy) $CI->order_by($orderBy, $direction);
$query = $CI->get();
return $query->result_array();
}
Applying your question to this.
$table = 'emails';
$joins[0][0] = 'user_email';
$joins[0][1] = 'user_email.user_id = emails.id';
$joins[0][2] = 'left';
$where['user_id'] = $userid;
You may add more join like $join1[0]..
If you need to select some specific column you can define in following manner
$select = 'table1.column1, table1.column2, table2.column1, table2.column2'
Or if you want all the columns put a *
$this->join_records($table, $joins, $where, $select);
You may also find it here.

How to separate the rows depending of the column's value witin two tables in CodeIgniter?

I have two tables: markers and markers_types.
markers
id, type_id, lat, lng
1 1 42.000 2.500
2 1 41.000 2.400
3 2 40.000 2.300
markers_types
id, name, image
1 TYPE1 type1.png
2 TYPE2 type2.png
How can I retrieve the rows from the DB correctly, so for example, if first row from markers have column type_id set to 1, I want to output an image from corresponding ID from the others table markers_types where markers.type_id is equal to markers_types.id ? Sorry for dumb question, but can't get it.
Here is my map_model.php:
class Map_model extends CI_Model{
...
function get_coordinates(){
$this->db->select('*');
$this->db->from('markers');
$query = $this->db->get();
if($query->result() < 1)
return false;
else{
$results = $query->result();
return $results;
}
}
}
And here is my app/controllers/map.php:
$dbresults = $this->map_model->get_coordinates();
foreach($dbresults as $item){
$marker = array();
$marker['position'] = $item->lat.','.$item->lng;
$marker['icon'] = base_url().'assets/img/ico/'.$item->image; // <-- I need to output here correct type image
$marker['infowindow_content'] = $item->description;
$this->googlemaps->add_marker($marker);
}
How can I mix them, so it will output appropriate image depending on the marker's type ?
I'am complete newbie at MySQL, so pls sorry in advance for that kind of basic question, I tried but didn't succeed to find out the right answer.
$query = $this->db->query("SELECT * FROM markers LEFT JOIN marker_types ON markers.type_id = markers_types.id");
// RETURNS AN ARRAY
$query->result_array();

Categories