我正在使用 Codeigniter,我正在尝试从两个表中调用信息:
产品: ID, 姓名, 价格, 描述, 类型Id
产品类型: t类别, 姓名
我正在尝试从产品中提取所有信息并使用 Product.typeID 来匹配 Product_Type 表,并且只提取 tName。大多数情况下,Product_Type 表中至少有 3 行具有相同的 typeID。示例:
产品 1 是一件 20 美元的红色衬衫,我需要大号、中号和小号的类型。
我已尝试使用 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
)
)
最佳答案
要让产品行包含一个列 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-clause 中写 any(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() 的进一步说明
在下面的查询中,我们不允许使用列name
,因为我们只按列id
分组。
SELECT
id,
name /* not allowed */
FROM
product
GROUP BY id
我们只能选择 group by
子句中的列。我们也可以使用不在 group by
子句中的列,尽管聚合函数如 max
和 group_concat
。
要解决这个问题,我们只需将列 name
添加到 group by
-clause
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 是主键,因此是唯一的。这意味着对于 id
列中的相同值,我们不能在 name
列中有不同的值。 {(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")
关于php - 从两个 Mysql 表中获取信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9373395/