laravelmysql用雄辩的语言应用产品过滤器(正确的查询是什么?)

hk8txs48  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(198)

我试图用雄辩的语言来过滤我的产品,但我对过滤器的where语句永远不会像现在这样工作。
我的数据库表如下所示:
这个 products table

+---------------+
| id | name     |
+---------------+
| 1  | product1 | 
| 2  | product2 |
| 3  | product3 | 
| 4  | product4 |
+---------------+

这个 properties table

+------------------------------------+
| id | property_group_id | value(int)|
+------------------------------------|
| 1  | 1                 | 20        |
| 2  | 1                 | 10        |
| 3  | 2                 | 2         |
| 4  | 2                 | 4         |
+------------------------------------+

这个 products_properties table

+--------------------------+
| product_id | property_id | 
+--------------------------|
| 1          | 1           |
| 1          | 3           |
| 2          | 2           |
| 2          | 4           |
+--------------------------+

我目前正在用eloquent生成的sql如下所示:

select * from `products` 
    where exists (
        select * from `properties`
            inner join `products_properties` 
                on `properties`.`id` = `products_properties`.`property_id` 
            where `products`.`id` = `products_properties`.`product_id` and 
            (
                `properties`.`property_group_id` = 1 and <--- property_group_id is not 
                `properties`.`value` >= 15 and                1 and 2 at the same time
                `properties`.`value` <= 25
            ) 
            and 
            (
                `properties`.`property_group_id` = 2 and
                `properties`.`value` >= 1 and 
                `properties`.`value` <= 2
            )
    )

我在找你 product1 但自从 property_group_id's 同一行不匹配。在两个where语句之间使用or也不起作用,因为只有其中一个必须为true才能找到某些内容。
sql是这样生成的:

$products = Product::with(['properties' => function($query){
        $query->with('propertyGroup');
    }])
    ->whereHas('properties', function ($query) {
        // Use filter when filter params are passed
        if(array_key_exists('filterGroupIds', $this->filter) && count($this->filter['filterGroupIds']) > 0){

            // Loop through filters
            foreach($this->filter['filterGroupIds'] as $filter){
                // Add where for each filter
                $query->where(
                    [
                        ["properties.property_group_id", "=", $filter['id']], // 1 or 2
                        ["properties.value", ">=", $filter['min']], // 15 or 1
                        ["properties.value", "<=", $filter['max']]  // 1 or 2
                    ]
                );
            }
        }

    })
    ->get();

要得到正确的结果,正确的查询是什么?如果可能的话,我的雄辩的代码将如何生成这个查询?

3qpi33ja

3qpi33ja1#

使用一个 whereHas() 条款per $filter :

$products = Product::with('properties.propertyGroup');
if(array_key_exists('filterGroupIds', $this->filter) && count($this->filter['filterGroupIds']) > 0) {
    foreach($this->filter['filterGroupIds'] as $filter) {
        $products->whereHas('properties', function ($query) {
            $query->where([...]);
        });
    }
}
9rnv2umw

9rnv2umw2#

SELECT * FROM properties p 
WHERE p.value BETWEEN minval AND maxval
JOIN product_properties pp ON p.id = pp.property_id
JOIN products pr ON pr.id = pp.product_id

请注意,这个查询根本没有经过优化,因为我不确切地知道所需的数据和行为,而且过滤是由属性id进行的,而不是由组id进行的,如果您希望由组进行,只需更改即可

p.id = pp.property_id

p.property_group_id = pp.property_id

对于有说服力的部分,试着自己去做并发布代码,但是首先需要定义模型之间的关系

相关问题