我有一个Order
模型和一个OrderStatus
模型。 Order
可以有多种状态,但只有一个“当前状态”。 (这由数据透视表created_at
上的order_status
时间戳定义。
Order
模型(orders
表)
OrderStatus
模型(order_statuses
表)
order_status
数据透视表(order_status
表)
如何定义查询范围(或类似)以获取某个状态的所有Orders
;即完成'?
以下内容不起作用,因为它检查订单的所有状态,即使是过去的状态。
public function scopeCompleted($query)
{
return $query->whereHas('statuses', function($q) {
return $q->where('statuses.id', 10);
});
}
生成的SQL是:
select *
from `orders`
where `orders`.`deleted_at` is null
and (
SELECT count(*)
from `statuses`
inner join `order_status` ON `statuses`.`id` = `order_status`.`status_id`
where `status`.`id` = `orders`.`id`
and `statuses`.`id` = ?
) >= 1
这错误地返回拥有的所有订单的ID为10的状态,而不是仅返回当前的状态ID为10的订单。 / p>
order_status 数据透视表
+----+----------+-----------------+-------------+---------------------+
| id | order_id | order_status_id | approver_id | approved_at |
+----+----------+-----------------+-------------+---------------------+
| 11 | 2 | 9 | NULL | 2017-04-10 13:33:25 |
+----+----------+-----------------+-------------+---------------------+
| 10 | 2 | 10 | NULL | 2017-04-10 13:33:25 |
+----+----------+-----------------+-------------+---------------------+
| 9 | 2 | 5 | NULL | 2017-04-10 13:33:25 |
+----+----------+-----------------+-------------+---------------------+
| 8 | 2 | 2 | NULL | 2017-04-10 13:33:25 |
+----+----------+-----------------+-------------+---------------------+
| 7 | 2 | 1 | NULL | 2017-04-10 13:33:25 |
+----+----------+-----------------+-------------+---------------------+
| 6 | 1 | 10 | NULL | 2017-04-10 13:32:09 |
+----+----------+-----------------+-------------+---------------------+
| 5 | 1 | 9 | NULL | 2017-04-10 13:32:05 |
+----+----------+-----------------+-------------+---------------------+
| 4 | 1 | 7 | NULL | 2017-04-10 13:32:05 |
+----+----------+-----------------+-------------+---------------------+
| 3 | 1 | 5 | NULL | 2017-04-10 13:32:05 |
+----+----------+-----------------+-------------+---------------------+
| 2 | 1 | 2 | NULL | 2017-04-10 13:32:05 |
+----+----------+-----------------+-------------+---------------------+
| 1 | 1 | 1 | NULL | 2017-04-10 13:32:05 |
+----+----------+-----------------+-------------+---------------------+
例如,上面的order_status
数据透视表显示了两个包含多个状态条目的订单。由此,当要求完成的订单(状态10)时,只有一个订单(ID为1的订单)应该返回,因为订单2不再完成,它已经用另一个状态更新。
答案 0 :(得分:0)
首先,这会更好:
select *
from `orders`
where `orders`.`deleted_at` is null
and EXISTS (
SELECT *
from `statuses`
inner join `order_status`
ON `statuses`.`id` = `order_status`.`status_id`
where `status`.`id` = `orders`.`id`
and `statuses`.`id` = ?
);
你真的不需要全部计数,你只需要知道是否存在。
但是查询是不可能的,因为没有提到status
表!
修复后,我们可以讨论如何避免子查询。