php - Laravel 5.1 获取已经完成的订单

标签 php mysql eloquent laravel-5.1 pivot-table

我有一个 Order 模型和一个 OrderStatus 模型。 Order 可以有多个状态,但只有一个“currentStatus”(这由数据透视表 order_status 上的 created_at 时间戳定义)。

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 状态的订单。

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 不再完成,已更新为另一个状态。

最佳答案

首先,这样会更好:

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表!

一旦你解决了这个问题,我们就可以讨论如何避免子查询。

关于php - Laravel 5.1 获取已经完成的订单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43327524/

相关文章:

php - WooCommerce - 页面重新加载时清空购物车

mysql - MySql 连接的性能问题,其中 2 列之间的值

mysql - 复制问题

mysql - 用反引号封装复杂的 mysql 插入

javascript - 如何使用ajax将检索到的数据分配给不同的td

php - 在 wordpress 循环中显示帖子的类别?

php - Eloquent:一个表中的两个外键指向同一个表

orm - Laravel中的多对多关系:belongsToMany()与hasManyThrough()

php - php rand函数有问题

php - Laravel Eloquent - 过滤器关系