PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

ALL-Operator in der WHERE-Klausel in Rails

Das ist ein Fall von .

Tatsächliche Tabellendefinitionen (Standard-1:n-Beziehung, verborgen durch das Ruby-ORM) sehen in etwa so aus:

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)
);

Ihr Versuch einer Abfrage versucht effektiv, jede einzelne Zeile in fees zu testen gegen mehrere Werte im gegebenen Array, was immer schlägt fehl, während Elemente des Arrays nicht identisch sind. Einer value darf nicht mit multiple identisch sein andere Werte. Sie brauchen einen anderen Ansatz:

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[]);

Dies setzt eindeutig voraus Werte in Ihrem Array und eindeutige Einträge in Ihren Tabellengebühren wie durch den UNIQUE erzwungen Einschränkung, die ich oben hinzugefügt habe. Andernfalls sind die Zählungen nicht zuverlässig und Sie müssen eine ausgefeiltere Abfrage verwenden. Hier ist ein Arsenal an Optionen:

Wie Sie sehen können, habe ich die Tabelle instructor_student nicht einbezogen überhaupt. Während die referenzielle Integrität mit einer FK-Einschränkung erzwungen wird (wie es normalerweise der Fall ist), können wir mit fees arbeiten allein, um die qualifizierende instructor_student_id zu bestimmen . Wenn Sie weitere Attribute aus der Haupttabelle abrufen müssen, tun Sie dies in einem zweiten Schritt, etwa:

SELECT i.*  -- or whatever you need
FROM   instructor_student i
JOIN  (
   SELECT ...  -- query from above
   ) f ON f.instructor_student_id = i.id
;