php – Laravel Eloquent多列IN条款

我最近开始使用Laravel进行开发,我的第一个项目是车辆预订应用程序.

我似乎做得很好,但我仍然试图用Eloquent显示当前的预订.

该系统的工作原理是将车辆添加到车辆表中,将员工添加到员工表中.使用employee_vehicle创建与数据透视表的多对多关系.

雇员

+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(10)     | NO   | PRI | NULL    | auto_increment |
| first_name | varchar(50) | NO   |     | NULL    |                |
| surname    | varchar(50) | NO   |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

车辆

+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| id           | int(10)     | NO   | PRI | NULL    | auto_increment |
| registration | varchar(10) | NO   |     | NULL    |                |
| make         | varchar(50) | NO   |     | NULL    |                |
| model        | varchar(50) | NO   |     | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+

employee_vehicle

+-------------+------------+------+-----+---------+----------------+
| Field       | Type       | Null | Key | Default | Extra          |
+-------------+------------+------+-----+---------+----------------+
| id          | int(10)    | NO   | PRI | NULL    | auto_increment |
| employee_id | int(10)    | NO   |     | NULL    |                |
| vehicle_id  | int(10)    | NO   |     | NULL    |                |
| direction   | varchar(3) | NO   |     | NULL    |                |
| date_booked | datetime   | NO   |     | NULL    |                |
| damaged     | tinyint(1) | NO   |     | NULL    |                |
| mileage     | int(10)    | NO   |     | NULL    |                |
+-------------+------------+------+-----+---------+----------------+

结果

+----+-------------+------------+-----------+---------------------+---------+---------+
| id | employee_id | vehicle_id | direction | date_booked         | damaged | mileage |
+----+-------------+------------+-----------+---------------------+---------+---------+
|  1 |           1 |          1 | OUT       | 2016-06-13 09:08:08 |       0 |    2357 |
|  2 |           1 |          1 | IN        | 2016-06-16 16:29:26 |       0 |    2401 |
|  3 |           2 |          1 | OUT       | 2016-06-20 10:47:28 |       0 |    2470 |
|  4 |           3 |          2 | OUT       | 2016-06-14 09:18:52 |       0 |    1403 |
+----+-------------+------------+-----------+---------------------+---------+---------+

这些表具有扩展Eloquent的Vehicle和Employee模型.这些方法调用belongsToMany.

我想要做的是获得车辆收集并急切地将员工加载到它上面.这样我就可以显示当前已预订的车辆,以及目前已将其预订的车辆.

例如:

$vehicleBookings = Vehicle :: with([’employees’]) – > get();

我将解释预订的方式……

基本上,车辆和员工使用枢轴表连接在一起.该表还记录了预订日期,预订方向(例如预订IN或OUT)以及有关其状况的其他数据等.

重要的是,IN和OUT都有一个条目,以便在预订之前和之后有车辆状况的审核日志.

我遇到的问题是能够从其可用的预订中获取最新的车辆状态,以确定它是否已预订或可预订.这决定了车辆可以做什么.

经过一番研究后,我想出了以下问题:

SELECT * 
FROM `employee_vehicle` 
WHERE (`vehicle_id`, `date_booked`) IN (
   SELECT `vehicle_id`, MAX(`date_booked`)
    FROM `employee_vehicle`
    GROUP BY `vehicle_id`
)

(我甚至不知道直到现在才能使用带有IN子句的多个列,但这很棒!).

这给了我:

+----+-------------+------------+-----------+---------------------+---------+---------+
| id | employee_id | vehicle_id | direction | date_booked         | damaged | mileage |
+----+-------------+------------+-----------+---------------------+---------+---------+
|  3 |           2 |          1 | OUT       | 2016-06-20 10:47:28 |       0 |    2470 |
|  4 |           3 |          2 | OUT       | 2016-06-14 09:18:52 |       0 |    1403 |
+----+-------------+------------+-----------+---------------------+---------+---------+

这给了我每辆车预订一排(这是在加入任何员工之前).

但是现在我真的被卡住了.我只是无法弄清楚如何使用也加入Employees的Eloquent编写等效查询. (它还需要只显示当前“OUT”的车辆,但我想这是微不足道的部分!)

我可以使用DB :: raw(‘…’)编写查询,并且不介意手动编写长SQL查询,但是我真的想要正确使用它,尝试使用Eloquent.

我注意到了whereIn方法,但它只接受一个列名的字符串而不是多列的数组,所以这是不行的. (除非我遗漏了某些东西,或者计划将来的Laravel版本?)

我从来不是一个真正的框架粉丝,并且需要一些令人信服的,而不是希望被击败,与Laravel一起.这让我感到很沮丧,因为我觉得不要乱用Eloquent会更快.如果我能让这个工作,那么我会更加接受它.

解决方法:

让我们说你

员工模型:

class Employee extends Model {
  protected $table = 'employees';
  public $timestamps = false;
}

和车型:

class Vehicle extends Model {
  protected $table = 'employees';
  public $timestamps = false;
}

并且您想获得按vehicle_id分组的最新日志.

所以制作一个模型:

class EmployeeVehicle extends Model {
  protected $table = 'employee_vehicle';
  public $timestamps = false;  

  public function employee() {
    return $this->belongsTo('App\Employee');
  }

  public function vehicle() {
    return $this->belongsTo('App\Vehicle');
  }
}

你对DB的要求就像:

$EmployeeVehicles = EmployeeVehicle::with(['employee', 'vehicle'])
                                  ->where('date_booked', '>', date('Y-m-d H:i:s', (time() - 3*30*24*60*60)))
                                  ->groupBy('vehicle_id')
                                  ->selectRaw('*, MAX(`date_booked`) AS `last_date_booked`')
                                  ->paginate(50);

附:我添加了where(‘date_booked’,’>’,date(‘Ymd H:i:s’,(time() – 3 * 30 * 24 * 60 * 60))因为您对日志数据库查询非常数据库引擎的工作量很大,通常情况下,过去3个月的数据可以保证性能安全.

并尝试分页,而不是得到一切.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...