Pregunta

Tengo problemas para escribir una consulta para las siguientes clases de dominio:

class Person {
  static hasMany = [memberships: Membership]
}

class Membership {

    static belongsTo = [person: Person, group: Group]

    Date joinDate = new Date();
    Group group;
    Person person;
}

class Group {
     static hasMany = [memberships: Membership]
}

Básicamente, quiero encontrar a todas las personas que pertenecen a una lista de grupos (digamos que los identificadores de grupo son (1,2) . El truco aquí es que la persona debe ser miembro de ambos grupos. Prefiero una consulta de criterios, pero HQL también está bien.

Tenga en cuenta que la consulta con algo como group.id en (1,2) no funcionará porque puede ser cualquiera de los grupos, no ambos .

¿Fue útil?

Solución

Ese es mi enfoque HQL simple:

Person.executeQuery("FROM Person x WHERE x IN (SELECT m.person from Membership m WHERE m.group = :group1) AND x IN (SELECT m.person from Membership m WHERE m.group = :group2)", [ group1: Group.get(1), group2: Group.get(2) ])

Saludos

Otros consejos

Tal vez no necesita una consulta. En la clase Persona, membresías es una lista de objetos de Membresía. Puede encontrar si un objeto está en una Colección (lista) sin hacer ninguna consulta. Algo como esto debería hacer el trabajo.

if(Person.memberships.contains(Membership.findByPersonAndGroup(person1,group1)) && Person.memberships.contains(Membership.findByPersonAndGroup(person1,group2))){
  ...do something...
}

Probablemente la otra solución sea más sencilla, pero creo que esta es solo otra opción.

Saludos

Groovy Collections

Problema interesante. No estoy seguro de que las soluciones anteriores sean genéricas en cuanto al número de grupos emparejados; en los casos hasta ahora, creo que es 2. Aunque probablemente haya una forma de hacerlos variables.

Otra forma que describo aquí en el panel de mensajes de griales - http://www.nabble.com/has-many-through-relationship-query---GORM--td23438096.html

Incluyendo el comentario del autor, Robert Fischer, de "Grails Persistence with GORM and GSQL".

@chadsmall

Este es otro enfoque que evita tener que agregar subconsultas a su cláusula WHERE mediante programación:

Consulta:

SELECT count(person.id) AS numPeople, person 
FROM Person as person 
INNER JOIN 
person.memberships AS mships
WITH mships.group.id IN (:groupIds) 
GROUP BY person.id 
HAVING COUNT(person.id) = (:numOfGroupIds)

Y algunos valores de ejemplo:

[
  groupIds: [8,9,439,86843]
  numOfGroupIds: 4
]

La parte de esta consulta hasta el GRUPO POR captura a todas las personas que coinciden con cualquiera de los grupos. Luego, al agrupar por persona y verificar que el número de resultados sea igual al número de grupos en la lista, puede verificar que esta persona es miembro de todos los grupos especificados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top