I am using Codeigniter and I am trying to call info from two tables:
Product:
id,
name,
price,
description,
typeId
Product_Type:
tCategory,
tName
I am trying to pull all info from Product and use Product.typeID to match to the Product_Type table and only pull back the tName. Most of the time there will be at least 3 rows from Product_Type table that will have the same typeID. Example:
Product 1 will be a red shirt for $20 and from type I will need Large, Medium and Small.
I have tried to doing this with JOIN but it gives me the 3 types I need but also duplicate the shirt info 3 times.
Here is my code:
$this->db->select('product.id, product.name, product.price, product.description, product_type.tName');
$this->db->from('product');
$this->db->where('perm_name', $id);
$this->db->join('product_type', 'product_type.tCategory = product.typeId', 'LEFT OUTER');
$query = $this->db->get();
Any help would be greatly appreciated.
EDIT:
Array
(
stdClass Object
(
[id] => 2
[name] => Tshirt 1
[price] => 20
[description] => Awesome tshirt
[tName] => 1
)
)
Array
(
[0] => stdClass Object
(
[tCategory] => 1
[tName] => Small
)
[1] => stdClass Object
(
[tCategory] => 1
[tName] => Medium
)
[2] => stdClass Object
(
[tCategory] => 1
[tName] => Large
)
)
To have a product row contain a column
typeswhich is populated with the rows of a 2nd table, you can either join both tables and play with group by:there is no magic behind max(product.name). you are not allowed to use columns in the select-clause that are not in the group by-clause or aggregated. since product.id is the primary key, we will only get one product.name for each product.id, so we don’t care which of the 3 product.name (from the join with the 3 types) gets selected. they are all the same. we could even write any(product.name) in the select-clause but i don’t think mysql supports this. =)
or do a correlated sub-query ~
i suggest to use the first query as it will be easier for mysql to optimize. for the record: i did not test those queries so it’s possible they need some tweaking. just let me know.
Edit1: Further explanation for using max()
In the following query we are not allowed to use the column
name, because we only grouped by the columnid.we may only select columns that are in the
group by-clause. we may also use columns, that are not in thegroup by-clause though aggregate functions likemaxandgroup_concat.to solve this problem we can just add the column
nameto thegroup by-clauseif we now have different values for
name, we will get more than one tuple in the result, e.g.:For the
producttable (id, name) = {(1, Alice), (1, Bob)} we get the resultbecause we grouped both columns.
the 2nd approach is using an aggregate function, like max:
For the
producttable (id, name) = {(1, Alice), (1, Bob)} we get the resultIn your example I assumed that the column product.id is the primary key and therefore unique. This means that we can not have different values in the
namecolumn for equal values in theidcolumn.{(1, Alice), (1, Bob)}is not possible, but maybe{(1, Alice), (2, Bob)}. If weGROUP BY product.idnow, we get a value forproduct.namefor each tuple in the group. But because theiddetermines thename, those values are all the same:will result in
after grouping it by product.id the result will look like
where
FandGare the aggregate functions used in theselect-clause. forFit does not matter which value we use, they are all the same. so we just usedmax. for g we usedgroup_concatto concat all values together.therefore
this will result in