Php 从两个Mysql表获取信息

Php 从两个Mysql表获取信息,php,mysql,codeigniter,Php,Mysql,Codeigniter,我正在使用Codeigniter,并尝试从两个表调用信息: 产品: 身份证件 名称 价格, 描述 类型ID 产品类型: t范畴, 名称 我正在尝试从Product中提取所有信息,并使用Product.typeID与Product_Type表匹配,只提取tName。大多数情况下,Product_Type表中至少有3行具有相同的typeID。例如: 产品1将是一件20美元的红色衬衫,I型需要大号、中号和小号 我已经试着用JOIN来做这件事,但是它给了我需要的3种类型,而且还复制了3次衬衫信息 这是我

我正在使用Codeigniter,并尝试从两个表调用信息:

产品: 身份证件 名称 价格, 描述 类型ID

产品类型: t范畴, 名称

我正在尝试从Product中提取所有信息,并使用Product.typeID与Product_Type表匹配,只提取tName。大多数情况下,Product_Type表中至少有3行具有相同的typeID。例如:

产品1将是一件20美元的红色衬衫,I型需要大号、中号和小号

我已经试着用JOIN来做这件事,但是它给了我需要的3种类型,而且还复制了3次衬衫信息

这是我的密码:

$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(); 
任何帮助都将不胜感激

编辑:


要使产品行包含一列
types
,该列由第二个表的行填充,您可以通过以下方式联接两个表并使用group:

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
max(product.name)背后没有魔力。不允许在select子句中使用不在group by子句中或未聚合的列。由于product.id是主键,因此每个product.id只能获得一个product.name,因此我们不关心选择3个product.name中的哪一个(从与3种类型的联接中)。他们都一样。我们甚至可以在select子句中写入任何(product.name),但我认为mysql不支持这一点

或者执行相关子查询~

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
我建议使用第一个查询,因为mysql更容易优化。作为记录:我没有测试这些查询,所以它们可能需要一些调整。请告诉我

Edit1:关于使用max()的进一步解释

在下面的查询中,我们不允许使用列
名称
,因为我们只按列
id
分组

SELECT
    id,
    name /* not allowed */

FROM
    product

GROUP BY id
我们只能选择
group by
-子句中的列。我们也可以使用不在
group by
-子句中的列,通过聚合函数,如
max
group\u concat

要解决这个问题,我们只需将列
name
添加到
groupby
-子句中即可

SELECT
    id,
    name /* ok because it's in group by */

FROM
    product

GROUP BY id, name
如果我们现在有不同的
name
值,我们将在结果中得到多个元组,例如:

对于
product
表(id,name)={(1,Alice),(1,Bob)},我们得到结果

1, Alice
1, Bob
1, Bob /* max(Alice,Bob) = Bob, because A < B */
因为我们把两列都分组了

第二种方法是使用聚合函数,如max:

SELECT
    id,
    max(name) /* ok because it's aggregated */

FROM
    product

GROUP BY id
对于
product
表(id,name)={(1,Alice),(1,Bob)},我们得到结果

1, Alice
1, Bob
1, Bob /* max(Alice,Bob) = Bob, because A < B */
将导致

(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)
(1, "White T-Shirt", "Small, Medium, Large"),
(2, "Black T-Shirt", "Small, Medium, Large")
按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))
其中
F
G
select
-子句中使用的聚合函数。对于
F
我们使用哪个值并不重要,它们都是相同的。所以我们只使用了
max
。对于g,我们使用
group_concat
将所有值合并在一起

所以

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"
这将导致

(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)
(1, "White T-Shirt", "Small, Medium, Large"),
(2, "Black T-Shirt", "Small, Medium, Large")

如果将产品复制3次,则join的on子句不起作用,并且使用笛卡尔乘积而不是左join。您能否提供一些导致您的问题的示例数据?我对product_type.tCategory和product.typeID列的内容特别感兴趣。尝试将“左外”替换为“左”。我添加了打印时的外观。它之所以说“左外”是因为我在试验这些设置,看看它们是否能产生我想要的效果。相关列不包括在内。您正在对product_type.t目录和product.typeID列执行联接。“left”连接只是“left-outer”连接的缩写。经过短暂的研究,我发现你用“left”来称呼它,例如,
$this->db->join('comments','comments.id=blogs.id','left')
product\u type.tCategory=product.typeID在我处理它时是一个错误,它应该是product\u type.tCategory=product.typeID,我在数组中放置的是使用“left”的结果。它仍然给我3个相同信息的数组。您使用$this->db->select()语句筛选出了相关列。我要求的是表格中的数据,而不是你的查询结果。如果我们看不到执行联接的列的值,我们几乎帮不了你。只需将
select*from product
select*from product_type
Awesome的结果放入即可,非常感谢您的宝贵时间。我希望你不介意,但还有一个问题,我不明白你为什么要使用max()sql命令,如果你不介意的话,你能进一步解释一下吗?我在下面添加了一些进一步的解释:Edit1:关于使用max()的进一步解释,希望对你有所帮助。