简体   繁体   English

从两个Mysql表获取信息

[英]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尽管它们是聚合函数,例如maxgroup_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. 其中FGselect -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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM