我正在使用Codeigniter,我正在尝试从两个表中调用信息:
产品: ID, 名称, 价钱, 描述, TYPEID
PRODUCT_TYPE: t类别, TNAME
我正在尝试从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();
非常感谢任何帮助。
编辑:
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
)
)
答案 0 :(得分:0)
要让产品行包含一列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
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更容易优化。记录:我没有测试那些查询,所以他们可能需要一些调整。请告诉我。
编辑1:使用max()
的进一步说明在以下查询中,我们不允许使用列name
,因为我们只按列id
分组。
SELECT
id,
name /* not allowed */
FROM
product
GROUP BY id
我们只能选择group by
- 子句中的列。我们也可以使用group by
- 子句中不包含max
和group_concat
等聚合函数的列。
要解决此问题,我们只需将name
列添加到group by
- 子句
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
因为我们将两个列分组。
第二种方法是使用聚合函数,如max:
SELECT
id,
max(name) /* ok because it's aggregated */
FROM
product
GROUP BY id
对于product
表(id,name)= {(1,Alice),(1,Bob)}我们得到结果
1, Bob /* max(Alice,Bob) = Bob, because A < B */
在您的示例中,我假设列product.id是主键,因此是唯一的。这意味着name
列中的id
列中的值相等,我们不能有不同的值。 {(1, Alice), (1, Bob)}
是不可能的,但也许{(1, Alice), (2, Bob)}
。如果我们现在GROUP BY product.id
,我们会为组中的每个元组获得product.name
的值。但由于id
确定了name
,因此这些值都是相同的:
SELECT
product.id,
product.name,
product_type.tName,
FROM
product
LEFT JOIN
product_type ON product.tName = product_types.tCategory
将导致
(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)
按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, Medium, Large"),
(2, "Black T-Shirt", "Small, Medium, Large")