【发布时间】:2020-04-29 19:01:17
【问题描述】:
我有一个查询,每个模型都有一些连接和全局范围,例如:
SELECT *
FROM products p
WHERE EXISTS(
SELECT *
FROM orders o
WHERE o.user_id = 4
AND o.status_id = 1
AND o.user_id = 3
AND EXISTS(
SELECT *
FROM suborders s
WHERE s.status_id = 2
)
);
这意味着我可以简单地编写一些whereHas 语句,并且我的查询将包含一些嵌套的EXIST 子句,但是所有全局范围(如orders 表上的user_id)都将自动应用:
$this->builder->whereHas('orders', function ($q) {
$q->where('status_id', '=', 1)
->whereHas('suborder', function ($q) {
$q->where('status_id', '=', 2);
});
});
问题是它很慢,使用普通的JOINs 而不是丑陋的嵌套EXIST 子句会更好:
SELECT *
FROM products p
INNER JOIN orders o ON p.order_id = o.id
INNER JOIN suborders s ON o.id = s.order_id
WHERE o.status_id = 1
AND u.user_id = 3
AND s.status_id = 2;
这个问题是我需要使用查询生成器来加入这些:
$this->builder->join('orders', 'products.order_id', '=', 'orders.id')
->join('suborders', 'orders.id', '=', 'suborders.order_id')
->where('orders.status_id', 1)
->where('suborders.id', 2);
这不包括我在Order 和Suborder 模型上的任何全局范围。我需要手动完成:
$this->builder->join('orders', 'products.order_id', '=', 'orders.id')
->join('suborders', 'orders.id', '=', 'suborders.order_id')
->where('orders.status_id', 1)
->where('suborders.id', 2)
->where('orders.user_id', 3);
这很糟糕,因为我每次编写这样的查询时都需要复制全局范围逻辑,而 whereHas 会自动应用它们。
有没有办法连接一个表,并自动应用连接模型中的所有全局范围?
【问题讨论】:
标签: php mysql sql laravel eloquent