Laravel Query Builder:意外输出

时间:2017-04-10 10:09:58

标签: php mysql laravel

在过去的两个小时里,我一直在努力使用Laravel查询生成器创建的MySQL查询,但我不理解为什么参数似乎被忽略。

查询构建器发出的查询如下:

select * from `deals` where
(
    (   
        `created_at` <= '2017-04-10 09:44:07' 
        and `valid_until` >= '2017-04-10 09:44:07'
    ) or (
        `created_at` <= '2017-04-10 09:44:07' 
        and `valid_until` <= '2017-04-10 09:44:07' 
        and `autodelete` = '2'
    ) or (
        `created_at` <= '2017-04-10 09:44:07'
        and `valid_until` <= '2017-04-10 09:44:07' 
        and `autodelete` = '0'
    ) or (
        `created_at` <= '2017-04-10 09:44:07'
        and `valid_until` is null
    )
    and `category_id` != '1'
) and `deals`.`deleted_at` is null
order by `order_date` desc, `created_at` desc 
limit 20 
offset 0

被忽略的部分是category_id的过滤。应排除具有category_id 1的项目,但它们不会被取消。我不明白为什么。

现在我发现当我把那个部分移到括号外面时,它会起作用。唯一的问题是:我没有将这些括号添加到查询中,似乎Laravel自动执行此操作,因为我使用了软删除。

这是我用于创建查询的代码:

        $query = Deal::query()
        ->where(function ($query) {
            // Active with an end date
            $query->where('created_at', '<=', date("Y-m-d H:i:s"))
            ->where('valid_until', '>=', date("Y-m-d H:i:s"));
        })
        ->orwhere(function ($query) {
            // Ended, but with possibility to upload a receipt
            $query->where('created_at', '<=', date("Y-m-d H:i:s"))
            ->where('valid_until', '<=', date("Y-m-d H:i:s"))
            ->where('autodelete', 2);
        })
        ->orwhere(function ($query) {
            // Ended, but keep it online
            $query->where('created_at', '<=', date("Y-m-d H:i:s"))
            ->where('valid_until', '<=', date("Y-m-d H:i:s"))
            ->where('autodelete', 0);
        })
        ->orwhere(function ($query) {
            // No end date
            $query->where('created_at', '<=', date("Y-m-d H:i:s"))
            ->where('valid_until', null);
        });

// Filter categories
if(!empty($deselectedCategories))
{
    foreach($deselectedCategories as $key => $val)
    {
        $query->where('category_id', '!=', $val);
    }
}

$deals = $query->orderBy('order_date', 'desc')->orderBy('created_at', 'desc')->paginate($resultsPerPage);

我必须忽视某些事情,我希望有人可以帮助我。非常感谢你提前!

1 个答案:

答案 0 :(得分:0)

请仔细查看参数分组https://laravel.com/docs/5.4/queries#parameter-grouping

我重新构建了查询

  1. 删除了and category_id!= {Val}以使用whereNotIn
  2. 重新调整查询

    $query = Deal::where(function
             ($query){
                $query->where(function ($query) {
                                        // Active with an end date
                    $query->where('created_at', '<=', date("Y-m-d H:i:s"))
                    ->where('valid_until', '>=', date("Y-m-d H:i:s"));
                })
                ->orwhere(function ($query) {
                    // Ended, but with possibility to upload a receipt
                    $query->where('created_at', '<=', date("Y-m-d H:i:s"))
                    ->where('valid_until', '<=', date("Y-m-d H:i:s"))
                    ->where('autodelete', 2);
                })
                ->orwhere(function ($query) {
                                        // Ended, but keep it online
                    $query->where('created_at', '<=', date("Y-m-d H:i:s"))
                    ->where('valid_until', '<=', date("Y-m-d H:i:s"))
                    ->where('autodelete', 0);
                })
                ->orwhere(function ($query) {
                                        // No end date
                    $query->where('created_at', '<=', date("Y-m-d H:i:s"))
                    ->where('valid_until', null);
                });
            });
    
          if (!empty($deselectedCategories)) {
              $catList =array();
              foreach ($deselectedCategories as $key => $val) {
                  $catList[] = $val;
              }
           $query->whereNotIn('category_id', $catList);
        }
    $query->whereNull('deleted_at');
    $deals = $query->orderBy('order_date', 'desc')->orderBy('created_at', 'desc')->paginate($resultsPerPage);