php - 从两个 Mysql 表中获取信息

标签 php mysql codeigniter

我正在使用 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 子句中的列,尽管聚合函数如 maxgroup_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))

其中 FGselect 子句中使用的聚合函数。对于 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/

相关文章:

php - 准确统计活跃用户? (PHP + MySQL)

mysql - 表中的多值属性

php - 如何检查 MySQL 中是否设置了位

php - 如何通过在 Configure.IT API 流程中使用来自 google geocode API 的地址来获取纬度和经度

php - 使用数组更新mysql数据库中的数据

php - 通过codeigniter将数据从android发布到mysql

PHP 转换跟踪

mysql - 每个表的总和和单个表的总和

php - 如何从 View 中调用 codeigniter Controller 函数

mysql - Codeigniter 通过 SSH 隧道连接到远程数据库