我有一个User
表和一个Appointment
表中所有约会的列表。一个用户可以预订多个约会,因此他们的最新约会可能与最高ID不同。
例如约会1的预定日期为7月16日。在约会1发生之前,用户决定也要早点预定,并在7月15日预订约会2。
我可以使用循环在每个用户的基础上获取ID,然后将它们组合在一起,但是出于好奇,我想知道如何在一个查询中做到这一点。
类似的东西:
User.joins(:appointments).group(:id).pluck("MAX(appointments.date)")
这只会获取日期,而不会获取具有该日期的约会的ID。尽管我的问题是ActiveRecord,但如果有人在SQL之类的解决方案上有解决方案,我相信我可以找到类似的功能。
答案 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 |
\------------------------------------------------/