Laravel (Lumen) Eloquent 在关系上使用 WHERE 查询(多级)
Laravel (Lumen) Eloquent querying with WHERE on a relation (Multi-level)
我有以下数据库 tables:
Purchase
-id
-workplace_id
Workplace
-id
-client_id
(显然还有更多字段,但对于示例来说,这些都是必需的)。
我想做这样的查询:
SELECT * FROM
purchase
INNER JOIN workplace ON (purchase.workplace_id = workplace.id)
WHERE
(workplace.client_id = 1)
我正在尝试使用 Eloquent 模型进行这项工作,但我不知道如何在连接的 table 上进行过滤。
我试过了:
$purchases = Purchase::query()
-> workplace()
-> where('client_id', '=', Auth::user() -> client_id)
-> get();
但显然 workplace() 由于某种原因未定义。
我的 Purchase.php 模型文件如下所示:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Purchase extends Model
{
public function workplace(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Workplace::class);
}
}
关于如何使这个简单的 select 工作的任何指示?
谢谢!
====编辑=====
我找到了一个可能的解决方案:
$purchases = Purchase::with('workplace')
-> whereHas('workplace', function($q) {
return $q -> where('client_id', '=', Auth::user() -> client_id);
})
-> get();
但这会生成一个 SQL,它看起来更复杂并且可能也更慢:
select * from `purchases` where exists (select * from `workplaces` where `purchases`.`workplace_id` =
`workplaces`.`id` and `client_id` = ? and `workplaces`.`deleted_at` is null)
所以我还在寻找更好的替代品
如果你想做一个连接,你需要用join
方法建立它,你不能使用关系。请在此处查看文档:
https://laravel.com/docs/9.x/queries#joins
所以你应该可以这样做:
$purchases = Purchase::query()
->join('workplace', 'purchase.workplace_id', '=', 'workplace.id')
->where('workplace.client_id', '=', Auth::user()->client_id)
->get();
您在编辑中显示的生成的 SQL 是 sub-query,您可能仍要考虑这一点。当然,sub-queries 通常比联接慢,但除非您处理的是海量数据集,否则性能差异可能可以忽略不计,并且它允许您使用本机 Eloquent 关系。
有关此问题的讨论,请参见此处:
我有以下数据库 tables:
Purchase
-id
-workplace_id
Workplace
-id
-client_id
(显然还有更多字段,但对于示例来说,这些都是必需的)。 我想做这样的查询:
SELECT * FROM
purchase
INNER JOIN workplace ON (purchase.workplace_id = workplace.id)
WHERE
(workplace.client_id = 1)
我正在尝试使用 Eloquent 模型进行这项工作,但我不知道如何在连接的 table 上进行过滤。 我试过了:
$purchases = Purchase::query()
-> workplace()
-> where('client_id', '=', Auth::user() -> client_id)
-> get();
但显然 workplace() 由于某种原因未定义。
我的 Purchase.php 模型文件如下所示:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Purchase extends Model
{
public function workplace(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(Workplace::class);
}
}
关于如何使这个简单的 select 工作的任何指示?
谢谢!
====编辑=====
我找到了一个可能的解决方案:
$purchases = Purchase::with('workplace')
-> whereHas('workplace', function($q) {
return $q -> where('client_id', '=', Auth::user() -> client_id);
})
-> get();
但这会生成一个 SQL,它看起来更复杂并且可能也更慢:
select * from `purchases` where exists (select * from `workplaces` where `purchases`.`workplace_id` =
`workplaces`.`id` and `client_id` = ? and `workplaces`.`deleted_at` is null)
所以我还在寻找更好的替代品
如果你想做一个连接,你需要用join
方法建立它,你不能使用关系。请在此处查看文档:
https://laravel.com/docs/9.x/queries#joins
所以你应该可以这样做:
$purchases = Purchase::query()
->join('workplace', 'purchase.workplace_id', '=', 'workplace.id')
->where('workplace.client_id', '=', Auth::user()->client_id)
->get();
您在编辑中显示的生成的 SQL 是 sub-query,您可能仍要考虑这一点。当然,sub-queries 通常比联接慢,但除非您处理的是海量数据集,否则性能差异可能可以忽略不计,并且它允许您使用本机 Eloquent 关系。
有关此问题的讨论,请参见此处: