ActiveRecord-选择用户最近约会的ID

时间:2019-06-12 19:07:34

标签: sql activerecord group-by

我有一个User表和一个Appointment表中所有约会的列表。一个用户可以预订多个约会,因此他们的最新约会可能与最高ID不同。

例如约会1的预定日期为7月16日。在约会1发生之前,用户决定也要早点预定,并在7月15日预订约会2。

我可以使用循环在每个用户的基础上获取ID,然后将它们组合在一起,但是出于好奇,我想知道如何在一个查询中做到这一点。

类似的东西:

User.joins(:appointments).group(:id).pluck("MAX(appointments.date)")

这只会获取日期,而不会获取具有该日期的约会的ID。尽管我的问题是ActiveRecord,但如果有人在SQL之类的解决方案上有解决方案,我相信我可以找到类似的功能。

1 个答案:

答案 0 :(得分:0)

恐怕我对ActiveRecord一无所知,但是在SQL中,我将使用条件小于条件的自我联接来实现这一目标。我设置了一些临时表来演示:

create table #User
(
    id int,
    fullName varchar(50)
)

create table #Appointment
(
    id int,
    userId int,
    apptDate date
)

insert into #User
values (1, 'John Smith'), (2, 'Jane Doe'), (3, 'Robert White'), (4, 'Sharon Black')

insert into #Appointment
values 
    (1, 3, '2019-08-01'),
    (2, 2, '2019-10-21'),
    (3, 1, '2019-07-16'), --John Smith Appointment 1, booked for July 16th
    (4, 4, '2019-09-28'),
    (5, 1, '2019-07-15') --John Smith Appointment 2, booked for July 15th

然后,您可以运行以下查询以返回每个用户及其最早的约会以及id和您想要的任何其他字段:

select
    u.fullName,
    a.id as EarliestAppId,
    a.apptDate as EarliestAppDate
from #User u
left join #Appointment a on u.id = a.userId
left join #Appointment earlier on u.id = earlier.userId and earlier.apptDate < a.apptDate
where earlier.id is null

这将返回以下结果,正确地标识了John Smith的2个约会中的较早的一个:

/------------------------------------------------\
| fullName     | EarliestAppId | EarliestAppDate |
|--------------|---------------|-----------------|
| John Smith   |       5       |    2019-07-15   |
| Jane Doe     |       2       |    2019-10-21   |
| Robert White |       1       |    2019-08-01   |
| Sharon Black |       4       |    2019-09-28   |
\------------------------------------------------/