在嵌套关系上添加 where 条件

Posted

技术标签:

【中文标题】在嵌套关系上添加 where 条件【英文标题】:Add where condition on a nested relationship 【发布时间】:2019-12-20 05:04:52 【问题描述】:

我正在尝试在我的模型的嵌套关系上添加 where 条件,如下所示:

SELECT *
FROM users u
INNER JOIN products p ON p.user_id = u.id
WHERE p.created_at > '2019-12-01';

我在 laravel 做的是:

$this->builder->where('products.date', '>', '2019-12-01');

而且它显然运行良好。问题是,如果我将其替换为:

$this->builder->whereHas('products', function ($query) 
  $query->where('date', '>', '2019-12-01');
);

它不再像预期的那样工作了。那是因为在第二种情况下,laravel 增加了如下查询:

and exists (SELECT * from products where users.id = products.user_id and date > '2019-12-01') 

所以在这种情况下,我的JOIN 不适用于我的 where 条件,我得到的结果太多。

有没有办法应用嵌套的where 条件,使用雄辩的关系,就像我的第一个例子一样?

【问题讨论】:

根据这篇文章,原始查询将是and exists (SELECT * from products where users.id = products.user_id and date > '2019-12-01') ,我想你忘了贴一些代码。 join products$this->builder->whereHas 之前也是如此吗?你能把你的代码贴在$this->builder 【参考方案1】:

在这种情况下使用with

$this->builder->with(['products'=>function ($query) 
  $query->where('date', '>', '2019-12-01');
]);

有了这个,你会得到usersproducts。但products 已过滤为date > 2019-12-01

您也可以使用carbonwhereDate 来做到这一点。

$date =Carbon\Carbon::parse('2019-12-01')->format('Y-m-d');

$this->builder->with(['products'=>function ($query) use($date) 
  $query->whereDate('date', '>', $date);
]);

【讨论】:

这有点用,因为我可以访问结果,但它不是作为 where 条件应用的 - 它只是为我提供了我可以单独获取的过滤数据。 此查询与您的第一个联接查询相同。如果您检查查询日志,那么您可以找出最后执行的查询是什么,请检查此链接。 artisansweb.net/how-to-log-query-in-laravel 如果你想在关系上使用 where 条件,那么你需要遵循查询构建器而不是关系。

以上是关于在嵌套关系上添加 where 条件的主要内容,如果未能解决你的问题,请参考以下文章

如何在laravel中的嵌套关​​系上放置where条件?

使用具有嵌套或条件的多个 where(或 AND)?

在 Bigquery 中使用 where 条件更新嵌套记录

雄辩地查询与嵌套 WHERE 的关系

sql语句中where条件的嵌套子查询性能

渴求式加载指定字段加载多个关联关系嵌套的渴求式加载带条件约束的渴求式加载