sql >> Databáze >  >> RDS >> Mysql

Průsečík dotazu s aktivním záznamem

Vaše otázka je pravděpodobně řešitelná bez průniku, něco jako:

Person.joins(:services).where(services: {service_type: [1,2]}).group(
   people: :id).having('COUNT("people"."id")=2')

Nicméně následující je obecný přístup, který používám pro vytváření křižovatek, jako jsou dotazy v ActiveRecord:

class Service < ActiveRecord::Base
  belongs_to :person

  def self.with_types(*types)
    where(service_type: types)
  end
end

class City < ActiveRecord::Base
  has_and_belongs_to_many :services
  has_many :people, inverse_of: :city
end

class Person < ActiveRecord::Base
  belongs_to :city, inverse_of: :people

  def self.with_cities(cities)
    where(city_id: cities)
  end

  def self.with_all_service_types(*types)
    types.map { |t|
      joins(:services).merge(Service.with_types t).select(:id)
    }.reduce(scoped) { |scope, subquery|
      scope.where(id: subquery)
    }
  end
end

Person.with_all_service_types(1, 2)
Person.with_all_service_types(1, 2).with_cities(City.where(name: 'Gold Coast'))

Vygeneruje SQL ve tvaru:

SELECT "people".*
  FROM "people"
 WHERE "people"."id" in (SELECT "people"."id" FROM ...)
   AND "people"."id" in (SELECT ...)
   AND ...

Výše uvedeným přístupem můžete vytvořit libovolný počet poddotazů na základě jakýchkoli podmínek/připojení atd., pokud každý poddotaz vrátí ID odpovídající osoby ve své sadě výsledků.

Každá sada výsledků poddotazu bude spojena součinem AND, čímž se sada shody omezí na průnik všech poddotazů.

AKTUALIZACE

Pro ty, kteří používají AR4, kde scoped byla odstraněna, moje druhá odpověď poskytuje sémanticky ekvivalentní scoped polyfil, který all není ekvivalentní náhradou navzdory tomu, co navrhuje dokumentace AR. Odpovězte zde:S Rails 4 je Model.scoped zastaralý, ale Model.all jej nemůže nahradit



  1. Jak používat Průvodce importem/exportem v SQL Server - SQL Server / Výukový program TSQL, část 104

  2. 115 hlavních otázek na pohovor SQL, které si musíte připravit v roce 2022

  3. Klauzule CHECK pro aktualizovatelná zobrazení

  4. Jak ROUND() funguje v MariaDB