Rails中WHERE子句中的ALL运算符
该关联如下所示。
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,fee.payment_status为“Due”,Fees.course_type为“每月”,fee_payment_notifications不应为“付费”。
并非总是存在fee_payment_notifications是强制性的。 所以,如果费用有fee_payment_notifications而不是它应该检查它的状态。 如果没有任何fee_payment_notifications比应该获取记录。 如果有任何fee_payment_notifications且状态为“付费”,则不应提取记录。
这是关系分裂的一个例子。
实际的表定义(标准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
约束强制执行的那样。 否则,计数不可靠,您必须使用更复杂的查询。 这是一个选项库:
- 如何以多次通过关系过滤SQL结果
如您所见,我根本没有涉及表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 ;
您可以将月份转换为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")
- Rails Postgresfunction索引
- PGError:错误:对象的AR查询及其has_many对象的WHERE子句中不允许聚合
- 具有正确的Rails命名和约定的“PG :: UndefinedTable:ERROR:relation不存在”
- Rails + PostGIS错误迁移数据库
- 使用Rails 4 Activerecord将多个列计数合并到单个查询中
- 在Rails + Postgres中按任意时间间隔计算记录的最佳方法
- Rails 5 db migration:如何修复ActiveRecord :: ConcurrentMigrationError
- Rails PostgreSQL数字字段溢出ERROR
- Rails和postgres – 在heroku上部署时忽略了pg gem