sql >> Databáze >  >> RDS >> PostgreSQL

ActiveRecord:Jak najít rodiče, jejichž VŠECHNY děti splňují podmínku?

Pomocí arel může vás dostat docela daleko. Záludná část je, jak nenapíšete celý dotaz pomocí arel vlastní syntaxi dotazu?

Zde je trik:při vytváření dotazu pomocí where , pokud používáte arel podmínky, získáte některé metody navíc zdarma. Například poddotaz, který tam máte, můžete omezit pomocí .exists.not , čímž získáte (NOT ( EXISTS (subquery))) Hoďte to do where rodiče -klauzule a máte hotovo.

Otázkou je, jak odkazujete na příslušné tabulky? K tomu potřebujete Arela. Mohli byste použijte Arelovo where s jeho ošklivými podmínkami jako a.eq b . Ale proč? Protože se jedná o podmínku rovnosti, můžete místo toho použít podmínky Rails! Na tabulku, na kterou se dotazujete, můžete odkazovat pomocí hash klíče, ale pro druhou tabulku (ve vnějším dotazu) můžete použít její arel_table . Podívejte se na toto:

parents = Parent.arel_table
Parent.where(
  Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)

Využití Arelu můžete dokonce snížit tím, že se trochu uchýlíte k řetězcům a spolehnete se na skutečnost, že můžete vkládat dílčí dotazy jako parametry do where Rails . Není to moc užitečné, ale nenutí vás to příliš vrtat v Arelových metodách, takže můžete použít ten trik nebo jiné SQL operátory, které převezmou poddotaz (existují ještě nějaké další?):

parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
  Child.where(parent_id: parents[:id], other_parent_id: nil)
)

Zde jsou dva hlavní body:

  • Můžete vytvářet poddotazy stejným způsobem, jakým jste zvyklí vytvářet běžné dotazy, odkazováním na tabulku vnějšího dotazu s Arel. Nemusí to být ani skutečný stůl, může to být alias! Bláznivé věci.
  • Jako parametry pro where Rails můžete použít poddotazy metoda je v pořádku.


  1. Problém s PHP $_SESSION

  2. Jak porovnat 2 po sobě jdoucí hodnoty řádků v objektu resultset pomocí pythonu

  3. Poskytovatel není kompatibilní s verzí chyby klienta Oracle při použití Oracle.DataClient

  4. Kombinace Oracle SQL MIN a MAX ze stejné tabulky