协会如下所示。
InstructorStudent has_many :fees
Fee belongs_to :instructor_student
我希望得到所有给定阵列中每月详细信息的教师学生。如果其中任何一个中没有月度详细信息,则不应返回任何记录。
due_month = ["2017-01-01","2017-02-01",,"2017-03-01"]
以下是我尝试过的查询,我想得到属于所有给定的三个due_month的InstructorStudent
,如果任何月份没有数据,那么它应该返回nil
:
@fee_paid =
InstructorStudent.first.joins(:fees).where("fees.monthly_detail =
ALL(ARRAY[?]::date[]) AND fees.course_type = ?", due_month.map{|i| i
},"per month");
修改1:
@ erwin-brandstetter这是我的最终查询
InstructorStudent.where("
instructor_students.Id IN (?)",Instructor.find(17).per_month_active_student
).joins(
"INNER JOIN fees ON fees.instructor_student_id = instructor_students.id LEFT OUTER JOIN fee_payment_notifications ON fee_payment_notifications.fee_id = fees.id"
).where(
"fee_payment_notifications.status <> ? AND
fees.monthly_detail = ANY(ARRAY[?]::date[]) AND
fees.course_type = ? AND
fees.payment_status <> ?"
, 'Paid',dueMonth,"per month", "Due"
).group(
'fees.instructor_student_id'
).
having(
'count(*) = ?', dueMonth.length
)
社团:
InstructorStudent has_many Fees
Fee belongs_to instructor_student
Fee has_many fee_payment_notifications
FeePaymentNotifications belongs to fee
这是我为取得教师学生所做的工作。其中包含fee.monthly_detail,其中包含dueMonth和fees.payment_status是“Due”,Fees.course_type是“每月” 和fee_payment_notifications不应该是“付费”。
并非总是存在fee_payment_notifications是强制性的。 因此,如果费用有fee_payment_notifications而不是它应该检查其状态。 如果没有任何fee_payment_notifications比应该获取记录。 如果有任何fee_payment_notifications且状态为“付费”,则不应提取记录。
答案 0 :(得分:2)
这是relational-division的案例。
实际的表定义(标准1:n关系,由Ruby ORM隐藏)将是这样的:
CREATE TABLE instructor_student (
id serial PRIMARY KEY
name ...
);
CREATE TABLE fees (
id serial PRIMARY KEY
, instructor_student_id integer NOT NULL REFERENCES instructor_student
, course_type ...
, monthly_detail date
, UNIQUE (instructor_student_id, course_type, monthly_detail)
);
您对查询的尝试有效地尝试针对给定数组中的多个值测试fees
中的每一行,当数组的元素不相同时,始终失败。 一个值不能与多个其他值相同。您需要一种不同的方法:
SELECT instructor_student_id
FROM fees
WHERE course_type = ?
AND monthly_detail = ANY(ARRAY[?]::date[]) -- ANY, not ALL!
GROUP BY instructor_student_id
HAVING count(*) = cardinality(ARRAY[?]::date[]);
这假设您的数组中的 不同 值以及表格费用中的唯一条目,例如我在上面添加的UNIQUE
约束强制执行。否则,计数不可靠,您必须使用更复杂的查询。以下是一系列选项:
如您所见,我根本没有涉及表格instructor_student
。虽然使用FK约束强制执行引用完整性(通常是这样),但我们可以单独使用fees
来确定符合条件的instructor_student_id
。如果您需要从主表中获取更多属性,请在第二步中执行此操作,例如:
SELECT i.* -- or whatever you need
FROM instructor_student i
JOIN (
SELECT ... -- query from above
) f ON f.instructor_student_id = i.id
;
答案 1 :(得分:0)
您可以将月份转换为Ruby的Date类,让ActiveRecord完成工作:
due_month= ["2017-01-01","2017-02-01","2017-03-01"]
fee_paid = InstructorStudent.joins(:fees).where("fees.monthly_detail" => due_month.map{|month| Date.parse month}, "fees.course_type" => "per month")