这是一个棘手的关系:
我有以下AR关系:
# Doctor
has_many :patients, through: :meetings, uniq: true
has_many :meetings
@ doctor.patients按预期工作,那里没什么了不起的。但是现在我想让一位医生按照作业的created_at命令(最新的)。
# Doctor
has_many :patients, through: :meetings, uniq: true, order: 'meetings.created_at DESC'
has_many :meetings
现在这不起作用(在Postgres 9上):“错误:对于SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中”。好吧,让我们这样做:
# Doctor
has_many :patients, through: :meetings, select: 'DISTINCT patients.*, meetings.created_at', order: 'meetings.created_at DESC'
has_many :meetings
这又有效,但患者不再是唯一的,因为DISTINCT正在处理整个SELECT子句。
是否有可能为所有患者取出所有患者,其中重复的患者被移除但仍在每个患者的最新会议中进行一次JOINed查询?
感谢您的提示!
更新
使用Oliver的提示我已经更新了如下关系:
# Doctor
has_many :patients,
through: :assignments,
select: 'patients.*, MAX(assignments.created_at) AS last_assignment',
group: 'patients.id',
order: 'last_assignment DESC',
counter_sql: proc { "SELECT COUNT(DISTINCT patients.id) FROM patients INNER JOIN assignments ON patients.id=assignments.patient_id WHERE assignments.doctor_id=#{id}" }
单独的counter_sql是必要的,因为Rails会替换整个select子句来为#count构建SQL。
有什么方法可以让它不那么笨重?
答案 0 :(得分:3)
尝试使用
MAX(meetings.created_at)
无处不在。像这样,即使患者有多次会议,您也会获得独特的患者记录。我的例子将选择最新的会议。如果您希望选择第一个,请使用MIN(meetings.created_at)
。
答案 1 :(得分:0)
试试这个:
has_many :patients,
through: :meetings,
order: 'meetings.created_at DESC',
conditions: 'row_number() over(partition by meetings.doctor_id, meetings.patient_id) order by meetings.created_at desc) = 1'
另一次尝试:
has_many :patients,
through: :meetings,
order: 'max(meetings.created_at) DESC',
group: 'patients.*',
select: 'patients.*'