que presentar perros perro los juego hacer gatos gato domesticos curiosidades convivencia convivan como bebe adulto adaptar acepte sql ruby-on-rails ruby-on-rails-3 activerecord

sql - presentar - perro y gato juego



¿Cómo encuentro al usuario que tiene tanto un gato como un perro? (9)

puedes obtener este resultado de varias maneras.

Espero que te ayude probar esto,

SELECT id FROM (SELECT user_id AS id FROM users INNER JOIN pets ON pets.user_id=users.id GROUP BY pets.user_id,pets.animal HAVING COUNT(pets.user_id)>0 AND (pets.animal=''cat'' OR pets.animal=''dog'') )AS s GROUP BY id HAVING COUNT(id)>1

Quiero hacer una búsqueda en 2 tablas que tienen una relación de varios a uno, por ejemplo

class User << ActiveRecord::Base has_many :pets end class Pet << ActiveRecord::Base belongs_to :users end

Ahora digamos que tengo algunos datos como ese

users id name 1 Bob 2 Joe 3 Brian pets id user_id animal 1 1 cat 2 1 dog 3 2 cat 4 3 dog

Lo que quiero hacer es crear una consulta de registro activa que devuelva a un usuario que tenga tanto un gato como un perro (es decir, usuario 1 - Bob).

Mi intento de esto hasta ahora es

User.joins(:pets).where(''pets.animal = ? AND pets.animal = ?'',''dog'',''cat'')

Ahora entiendo por qué esto no funciona: está buscando una mascota que sea tanto un perro como un gato, por lo que no devuelve nada. Sin embargo, no sé cómo modificar esto para darme la respuesta que deseo. ¿Alguien tiene alguna sugerencia? Parece que debería ser fácil, no parece ser una situación especialmente inusual.

---editar---

Solo agregué un poco de coda a esta pregunta ya que acabo de descubrir a Squeel . Esto le permite crear una subconsulta como tal;

User.where{id.in(Pet.where{animal == ''Cat''}.select{user_id} & id.in(Pet.where{animal == ''Dog''}.select{user_id}))

Esto es lo que encontrará en mi aplicación.


El enfoque habitual es filtrar gatos o perros en la cláusula where . Luego, user_id en user_id y exija que el grupo resultante having count(distinct pet.id) = 2 .

No estoy seguro de cómo se expresa having en ActiveRecord; esta publicación parece contener una solución.


Use sub-selects para restringir los resultados:

User.joins(:pets).where( ''id IN (SELECT user_id FROM pets WHERE animal = ?) AND id IN (SELECT user_id FROM pets WHERE animal = ?)'', ''cat'', ''dog'')


Esto debería ser útil. prueba esto

seleccione u. * de los usuarios u, mascotas p1 donde u.id = p1.user_id AND p1.animal = "cat" AND p1.user_id in (seleccione user_id de mascotas donde animal = ''perro'')


Raramente respondo preguntas sobre SO, pero lo intentaré. :)

SELECT name FROM users WHERE id IN (SELECT a.user_id FROM ( (SELECT user_id FROM pets WHERE animal = ''cat'') a INNER JOIN (SELECT user_id FROM pets WHERE animal = ''dog'') b ON a.user_id = b.user_id ));


Hay varias maneras de hacerlo: algunas de las anteriores funcionarán; también, aquí hay un enfoque ligeramente diferente que utiliza esencialmente ''vistas'', esencialmente, heredando de su clase genérica de ''mascotas'' en dos clases separadas (gatos y perros).

SELECT id, name FROM users INNER JOIN ( SELECT DISTINCT user_id as belongs_to FROM pets WHERE animal = ''dog'' ) dog ON users.id = dog.belongs_to INNER JOIN ( SELECT DISTINCT user_id as belongs_to FROM pets WHERE animal = ''cat'' ) cat ON users.id = cat.belongs_to


para esta pregunta hay tantas maneras de obtener una solución que puede hacer lo siguiente también ...

select dog_table.user_name from ( select * FROM users,pets where pets.user_id = users.id and pets.animal = ''dog'' ) dog_table, ( select * FROM users,pets where pets.user_id = users.id and pets.animal = ''cat'' ) cat_table where dog_table.user_id = cat_table.user_id


Andomar: desafortunadamente, escribir la consulta de esa manera no siempre funcionará como se desee. Específicamente, tener 2 gatos hará que aparezca el usuario, y tener 3 mascotas, por ejemplo, 2 gatos y un perro, hará que se excluyan.
No sé mucho sobre ActiveRecord, pero la siguiente es la sintaxis SQL estándar que funcionaría:

SELECT users.id FROM Users JOIN (SELECT user_id FROM Pets WHERE animal IN (''dog'', ''cat'') GROUP BY user_id HAVING COUNT(DISTINCT animal)) Pets ON Pets.user_id = Users.id

Esto funciona de manera diferente a las versiones existentes contando el "tipo" distinto de mascota ( ''cat'' versus ''dog'' ).


Aquí hay otra solución. Poco más Rails friendly ..

User.all(:select => "DISTINCT users.*", :joins=>[:pets, :pets], :conditions => ["pets.animal = ? AND pets_users.animal = ?", "cat", "dog"])

Lea este artículo sobre los méritos relativos de usar JOIN vs GROUP BY + HAVING para dicha solución.

Refiérase a esta pregunta SO que discute este problema en detalle.