草庐IT

php - Laravel Eloquent 多列 IN 子句

coder 2023-10-13 原文

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

我似乎做得很好,但是我无法尝试使用 Eloquent 显示当前预订。

系统的工作原理是将车辆添加到vehicles 表,将员工添加到employees 表。使用 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    |                |
+--------------+-------------+------+-----+---------+----------------+

员工车辆

+-------------+------------+------+-----+---------+----------------+
| 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 的 VehicleEmployee 模型。这些具有调用 belongsToMany 的方法。

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

例如:

$vehicleBookings = Vehicle::with(['employees'])->get();

我将解释预订的工作方式...

基本上,车辆和员工使用数据透视表链接在一起。该表还记录了预订日期、预订方向(例如预订入或出),以及有关其状况的其他数据等。

重要的是,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 |
+----+-------------+------------+-----------+---------------------+---------+---------+

这为我提供了每辆曾经预订过的车辆的一行(这是在加入任何员工之前)。

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

可以只使用 DB::raw('...') 编写查询,并且不介意手动编写长 SQL 查询,但是我 < em="">真的想尝试一下,尝试使用 Eloquent。

我注意到了 whereIn 方法,但它只接受一个列名称的字符串而不是多列的数组,所以这是不行的。 (除非我遗漏了什么,或者它计划用于 Laravel 的 future 版本?)

我从来都不是框架的真正粉丝,需要一些说服力,并且不想被打败,一直坚持使用 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('Y-m-d H:i:s', (time() - 3*30*24*60*60)) 因为你的查询日志数据库对于数据库引擎来说是一项非常繁重的工作,为了性能安全,通常最好有过去 3 个月的数据。

并尝试分页,而不是获取所有内容。

关于php - Laravel Eloquent 多列 IN 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37954462/

有关php - Laravel Eloquent 多列 IN 子句的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - Rails 3 I18 : translation missing: da. datetime.distance_in_words.about_x_hours - 2

    我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment

  4. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  5. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  6. ruby-on-rails - rails : check if the model was really saved in after_save - 2

    ActiveRecord用于在每次调用保存方法时调用after_save回调,即使模型没有更改并且没有生成插入/更新查询也是如此。这实际上是默认行为。在大多数情况下这没问题。但是一些after_save回调对模型是否实际保存的事情很敏感。有没有办法确定模型是否实际保存在after_save中?我正在运行以下测试代码:classStage 最佳答案 ActiveRecordusetocallafter_savecallbackeachtimesavemethodiscalledevenifthemodelwasnotchangedan

  7. ruby-on-rails - Rails 单选按钮 - 模型中多列的一种选择 - 2

    我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模

  8. ruby-on-rails - ruby 范围 : operators in case statement - 2

    我想检查my_number是否在某个范围内,包括较高的值。在IF语句中我会简单地使用“x>100&&x但是我应该在Ruby案例中做什么(开关)?使用:casemy_numberwhenmy_number不起作用。备注:标准范围不包括my_number恰好为500的情况,并且我不想添加第二个“when”,因为我必须编写双重内容casemy_number#between100and500when100..500puts"Correct,dosomething"when500puts"Correct,dosomethingagain"end 最佳答案

  9. ruby - Chef : Read variable from file and use it in one converge - 2

    我有以下代码,它下载一个文件,然后将文件的内容读入一个变量。使用该变量,它执行一个命令。这个配方不会收敛,因为/root/foo在编译阶段不存在。我可以通过多个聚合和一个来解决这个问题ifFile.exist但我想用一个收敛来完成它。关于如何做到这一点有什么想法吗?execute'download_joiner'docommand"awss3cps3://bucket/foo/root/foo"not_if{::File.exist?('/root/foo')}endpassword=::File.read('/root/foo').chompexecute'join_domain'd

  10. ruby 代码 : why put colon in front of variable name (inside initialize method) - 2

    我遇到了一些Ruby代码,我试图理解为什么变量在initialize方法声明中的名称末尾有冒号。冒号有什么原因吗?attr_reader:var1,:var2definitialize(var1:,var2:)@var1=var1@var2=var2end 最佳答案 那些是关键字参数。您可以按名称而非位置使用它们。例如ThatClass.new(var1:42,var2:"foo")或ThatClass.new(var2:"foo",var1:42)Anarticleaboutkeywordargumentsbythoughtbot

随机推荐