Php 拉威尔不可能在哪里查询

Php 拉威尔不可能在哪里查询,php,mysql,laravel,Php,Mysql,Laravel,我正在为一些产品做过滤器。我的大部分工作正常,但是我遇到了一个错误,有一个不可能的where子句 该表包含单个产品的多行,我试图匹配每个产品的多个条件,这导致它失败 如果您对此有意见,或者可能有解决方法,我将不胜感激 数据库表如下所示: -------------------------------------------- |id | FilterKey | filterValue | product_id | ---------------------------------

我正在为一些产品做过滤器。我的大部分工作正常,但是我遇到了一个错误,有一个不可能的
where
子句

该表包含单个产品的多行,我试图匹配每个产品的多个条件,这导致它失败

如果您对此有意见,或者可能有解决方法,我将不胜感激

数据库表如下所示:

-------------------------------------------- |id | FilterKey | filterValue | product_id | -------------------------------------------- |1 | Colour | Gunmetal | 1 | |2 | Colour | Silver | 1 | |3 | Size | 750cc | 1 | |4 | Size | 1000cc | 1 | |5 | Colour | Red | 2 | |6 | Colour | Blue | 2 | |7 | Size | 750cc | 2 | |8 | Size | 1000cc | 2 | --------------------------------------------
public function scopeFilterProduct($query, $filters)
{
    $this->filters = $filters;
    if (count ($this->filters) === 1 && isset($this->filters[0]))
    {
        return $query;
    }
    $query->join('product_filters', 'products.id', '=', 'product_filters.product_id')->Where(function($query){
        foreach ($this->filters as $filter => $vals)
        {
            $this->filter = $filter;
            $this->vals = $vals;
            $query->Where(function ($query){

                $query->Where('filterKey', $this->filter); 

                $query->Where(function($query){
                    foreach ($this->vals as $val){

                        $query->orWhere('filterValue', $val); 
                    }
                    $this->vals = null;
                });

            });
            $this->filter = null;
        };
    }); 
    return $query;
}
class Filter extends Model
{
    protected $fillable = ['id', 'name'];

    public function products()
    {
        return $this->belongsToMany(Product::class, 'products_filters');          
    } 
}
然后输出以下SQL语句:

select
  distinct
    `products`.`id`
  , `product_id`
from
 `products`
inner join
 `product_filters`
on
 `products`.`id` = `product_filters`.`product_id`
where 
     (
         (`filterKey` = 'Colour' and (`filterValue` = 'gunmetal'))
       and
         (`filterKey` = 'Size' and (`filterValue` = '750cc'))
     )
     and
       `products`.`deleted_at` is null


如果选中,如屏幕截图所示,则页面上只应显示“产品一”。

我认为您添加的范围是错误的。在我看来,甚至你的数据库结构也不正确。以下是我将如何构建此结构:

过滤器表 此模型将保存所有过滤器值。例如,
颜色
大小
等。以下是筛选表的结构:

-----------------
|id | name      |
-----------------
|1  | Colour    |
|2  | Size      |
-----------------
--------------------------------------------
|id | filter_id | filterValue | product_id |
--------------------------------------------
|1  | 1         | Gunmetal    | 1          |
|2  | 1         | Silver      | 1          |
|3  | 2         | 750cc       | 1          |
|4  | 2         | 1000cc      | 1          |
|5  | 1         | Red         | 2          |
|6  | 1         | Blue        | 2          |
|7  | 2         | 750cc       | 2          |
|8  | 2         | 1000cc      | 2          |
--------------------------------------------
所以你的雄辩模型变成了这样:

-------------------------------------------- |id | FilterKey | filterValue | product_id | -------------------------------------------- |1 | Colour | Gunmetal | 1 | |2 | Colour | Silver | 1 | |3 | Size | 750cc | 1 | |4 | Size | 1000cc | 1 | |5 | Colour | Red | 2 | |6 | Colour | Blue | 2 | |7 | Size | 750cc | 2 | |8 | Size | 1000cc | 2 | --------------------------------------------
public function scopeFilterProduct($query, $filters)
{
    $this->filters = $filters;
    if (count ($this->filters) === 1 && isset($this->filters[0]))
    {
        return $query;
    }
    $query->join('product_filters', 'products.id', '=', 'product_filters.product_id')->Where(function($query){
        foreach ($this->filters as $filter => $vals)
        {
            $this->filter = $filter;
            $this->vals = $vals;
            $query->Where(function ($query){

                $query->Where('filterKey', $this->filter); 

                $query->Where(function($query){
                    foreach ($this->vals as $val){

                        $query->orWhere('filterValue', $val); 
                    }
                    $this->vals = null;
                });

            });
            $this->filter = null;
        };
    }); 
    return $query;
}
class Filter extends Model
{
    protected $fillable = ['id', 'name'];

    public function products()
    {
        return $this->belongsToMany(Product::class, 'products_filters');          
    } 
}
产品表 您的产品型号变为:

class Product extends Model
{
    public function filters()
    {
        return $this->belongsToMany(Filter::class, 'products_filters');          
    } 
}
产品过滤器表 在进行上述更改后,以下是表格的结构:

-----------------
|id | name      |
-----------------
|1  | Colour    |
|2  | Size      |
-----------------
--------------------------------------------
|id | filter_id | filterValue | product_id |
--------------------------------------------
|1  | 1         | Gunmetal    | 1          |
|2  | 1         | Silver      | 1          |
|3  | 2         | 750cc       | 1          |
|4  | 2         | 1000cc      | 1          |
|5  | 1         | Red         | 2          |
|6  | 1         | Blue        | 2          |
|7  | 2         | 750cc       | 2          |
|8  | 2         | 1000cc      | 2          |
--------------------------------------------
现在,您可以简单地查询filters表,然后获取所有过滤器的关联产品。之后,您只需编写一份独特产品的列表

根据选定的筛选器取消查询产品。 在您看来,您需要写:

@foreach($products as $product)
// Your product block HTML
@endforeach

这被称为集合划分。遵循的逻辑是“获取一个不存在所选过滤器的产品”,谢谢Raza,我现在正在研究实现它。希望这能解决它。为了帮助,你会如何考虑拉动一个产品,它正好匹配过滤器的2?更新我的答案来描述我将如何过滤基于提供的产品过滤器独特的产品。