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

Getting specific products from database with one-to-many relationship

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


产品

|编号—— |名称 ----- |价格 -- |

| 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
            )    
    )

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

在原始 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