[英]Getting info from two Mysql Tables
I am using Codeigniter and I am trying to call info from two tables: 我正在使用Codeigniter,并且尝试从两个表中调用信息:
Product: id, name, price, description, typeId 产品:id,名称,价格,描述,typeId
Product_Type: tCategory, tName 产品类型: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. 我正在尝试从Product中提取所有信息,并使用Product.typeID来匹配Product_Type表,而仅返回tName。 Most of the time there will be at least 3 rows from Product_Type table that will have the same typeID. 大多数情况下,Product_Type表中至少会有3行具有相同的typeID。 Example: 例:
Product 1 will be a red shirt for $20 and from type I will need Large, Medium and Small. 产品1将是一件售价为20美元的红色衬衫,而从类型I中将需要大,中和小。
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. 我尝试使用JOIN进行此操作,但是它给了我所需的3种类型,但也将衬衫信息重复了3次。
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 types
which is populated with the rows of a 2nd table, you can either join both tables and play with group by: 要使一个产品行包含一个填充有第二个表的行的列types
,您可以将两个表连接起来并使用group by进行操作:
SELECT
product.id,
max(product.name) as name,
max(product.price) as price,
max(product.description) as description,
group_concat(product_types.tName) as types
FROM
product
LEFT JOIN
product_type ON product.tName = product_types.tCategory
GROUP BY product.id
there is no magic behind max(product.name). 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. 由于product.id是主键,因此每个product.id只会获得一个product.name,因此我们不在乎选择3个product.name(来自3种类型的联接)中的哪个。 they are all the same. 他们都是一样的。 we could even write any(product.name) in the select-clause but i don't think mysql supports this. 我们甚至可以在选择子句中写any(product.name),但是我不认为mysql支持这一点。 =) =)
or do a correlated sub-query ~ 或者做一个相关的子查询〜
SELECT
product.id,
product.name,
product.price,
product.description,
(SELECT
group_concat(product_types.tName)
FROM product_types
WHERE product.tName = product_types.tCategory
GROUP BY product_types.tCategory
) as types
FROM
product
i suggest to use the first query as it will be easier for mysql to optimize. 我建议使用第一个查询,因为这将使mysql优化更加容易。 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() Edit1:有关使用max()的进一步说明
In the following query we are not allowed to use the column name
, because we only grouped by the column id
. 在以下查询中,我们不允许使用列name
,因为我们仅按列id
分组。
SELECT
id,
name /* not allowed */
FROM
product
GROUP BY id
we may only select columns that are in the group by
-clause. 我们只能group by
-clause选择组中的列。 we may also use columns, that are not in the group by
-clause though aggregate functions like max
and group_concat
. 我们也可以使用列,但这些列不在group_concat
group by
尽管它们是聚合函数,例如max
和group_concat
。
to solve this problem we can just add the column name
to the group by
-clause 为了解决这个问题,我们可以group by
-clause将列name
添加到group by
SELECT
id,
name /* ok because it's in group by */
FROM
product
GROUP BY id, name
if we now have different values for name
, we will get more than one tuple in the result, eg: 如果我们现在具有不同的name
值,则结果中将得到多个元组,例如:
For the product
table (id, name) = {(1, Alice), (1, Bob)} we get the result 对于product
表(id,name)= {(1,Alice),(1,Bob)},我们得到结果
1, Alice
1, Bob
because we grouped both columns. 因为我们将这两列都分组了。
the 2nd approach is using an aggregate function, like max: 第二种方法是使用聚合函数,例如max:
SELECT
id,
max(name) /* ok because it's aggregated */
FROM
product
GROUP BY id
For the product
table (id, name) = {(1, Alice), (1, Bob)} we get the result 对于product
表(id,name)= {(1,Alice),(1,Bob)},我们得到结果
1, Bob /* max(Alice,Bob) = Bob, because A < B */
In your example I assumed that the column product.id is the primary key and therefore unique. 在您的示例中,我假设product.id列是主键,因此是唯一的。 This means that we can not have different values in the name
column for equal values in the id
column. 这意味着在id
列中,相等的值不能在name
列中具有不同的值。 {(1, Alice), (1, Bob)}
is not possible, but maybe {(1, Alice), (2, Bob)}
. {(1, Alice), (1, Bob)}
是不可能的,但可能是{(1, Alice), (2, Bob)}
。 If we GROUP BY product.id
now, we get a value for product.name
for each tuple in the group. 如果现在对GROUP BY product.id
进行分组,则将获得组中每个元组的product.name
值。 But because the id
determines the name
, those values are all the same: 但是由于id
决定了name
,所以这些值都相同:
SELECT
product.id,
product.name,
product_type.tName,
FROM
product
LEFT JOIN
product_type ON product.tName = product_types.tCategory
will result in 将导致
(1, "White T-Shirt", Small),
(1, "White T-Shirt", Medium),
(1, "White T-Shirt", Large),
(2, "Black T-Shirt", Small),
(2, "Black T-Shirt", Medium),
(2, "Black T-Shirt", Large)
after grouping it by product.id the result will look like 按product.id分组后,结果将如下所示
(1, F("White T-Shirt", "White T-Shirt", "White T-Shirt"),
G(Small, Medium, Large)),
(2, F("Black T-Shirt", "Black T-Shirt", "Black T-Shirt"),
G(Small, Medium, Large))
where F
and G
are the aggregate functions used in the select
-clause. 其中F
和G
是select
-clause中使用的聚合函数。 for F
it does not matter which value we use, they are all the same. 对于F
,我们使用哪个值都没有关系,它们都是相同的。 so we just used max
. 所以我们只用了max
。 for g we used group_concat
to concat all values together. 对于g,我们使用group_concat
将所有值连接在一起。
therefore 因此
F("White T-Shirt", "White T-Shirt", "White T-Shirt") = "White T-Shirt"
F("Black T-Shirt", "Black T-Shirt", "Black T-Shirt") = "Black T-Shirt"
G(Small, Medium, Large) = "Small, Medium, Large"
this will result in 这将导致
(1, "White T-Shirt", "Small, Medium, Large"),
(2, "Black T-Shirt", "Small, Medium, Large")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.