从数据库中获取具有一对多关系的特定产品

Posted

技术标签:

【中文标题】从数据库中获取具有一对多关系的特定产品【英文标题】:Getting specific products from database with one-to-many relationship 【发布时间】:2021-10-17 18:55:52 【问题描述】:

我正在使用 mysqlphp 框架 Codeigniter 4 制作产品目录。这里我将展示一个简化的示例。我的数据库中有两个表。一个具有通用数据,例如产品名称和价格。另一种具有各种属性,例如颜色,材料等。因此,一种产品具有许多属性。类似的东西:


产品

|身份证——|姓名 ----- |价格——|

| 0 --- |椅子 1 -- | 50 ----- |

| 1 --- |椅子 2 -- | 75 ----- |


属性

|身份证——| product_id -- |属性 -- |价值——|

| 0 --- | 0 ------------ |颜色 ------ |黑色 -- |

| 1 --- | 0 ------------ |尺寸-------- |小——|

| 2 --- | 1 ------------ |颜色 ------ |白色 -- |

| 3 --- | 1 ------------ |尺寸-------- |大——|


我的问题涉及获取特定产品,例如当有产品过滤器并且用户希望查看具有特定属性的所有产品时。如果我需要获得一种具有一种属性的产品,那我没有问题。我这样做:

$product = $productsModel->join('attributes', 'attributes.product_id = products.id')
                         ->where('attribute', 'color')
                         ->where('value', 'black')
                         ->find();

但是我无法根据多个属性获取产品。就像我需要一把黑色小的椅子,我不能添加->where('attribute', 'size')->where('value', 'small'),因为颜色和大小是不同的行。很容易看出我是否使用相同的join,并尝试获取id为0的产品。结果是:

Array
    (
        [0] => Array
            (
                [id] => 0
                [name] => Chair 1
                [price] => 50
                [product_id] => 1
                [attribute] => color
                [value] => black
            )    
        [1] => Array
            (
                [id] => 1
                [name] => Chair 1
                [price] => 50
                [product_id] => 0
                [attribute] => size
                [value] => small
            )    
    )

知道如何解决这个问题吗?我需要创建一个带有复选框的过滤器,它将显示产品的所有可用属性并允许用户搜索任何组合。

【问题讨论】:

发布问题后,我发现表格看起来不像预览中的样子。所以我试图手动制作它们。希望他们是可以理解的。 您需要与属性表进行第二次联接。您应该使用表名别名来防止两次使用相同的表名。抱歉,没有答案,因为我没有使用 Codeigniter 的经验。我猜你可以这样做:->join('attributes AS A1',....->join('attributes AS A2',....? 对不起,我真的不明白第二次加入应该是什么。我可以请你举个例子吗?可以是原始的SQL查询,我会理解的 好的,我会在原始 SQL 中尝试答案。 有关索引 many:many 表的建议请参阅此内容:mysql.rjweb.org/doc.php/… 【参考方案1】:

在原始 MySQL 中,您当前的查询为:

SELECT products.*
FROM products 
INNER JOIN attributes ON attributes.product_id = products.id
WHERE attribute = 'color' AND value = 'black';

添加第二个连接可能如下所示:

SELECT P.*
FROM products AS P
INNER JOIN attributes AS A1 ON A1.product_id = P.id
INNER JOIN attributes AS A2 ON A2.product_id = P.id
WHERE A1.attribute = 'color' AND A1.value = 'black' AND
      A2.attribute = 'size'  AND A2.value = 'small';

见:https://www.mysqltutorial.org/mysql-inner-join.aspx

【讨论】:

以上是关于从数据库中获取具有一对多关系的特定产品的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django 查询从一对多关系中获取数据

NSPredicate 用于从一对多关系中获取项目,不包括特定的相关实体

如何在一对多核心数据关系中获取特定数据?

核心数据 - 以一对多关系访问实例与获取请求?

如何从一对多单向关系中获取“多”部分中的对象?

如何使用 ADO.NET 从具有一对多关系的 DAL 层中的多个表中返回数据