Sumair Rasool:
Tengo una persona mesa, que es así,
personas
id | name
1 | Alex
2 | Jack
3 | Roy
Tengo una otra tabla
propiedades
id | title | format
1 | Age | number
2 | Plays Football | checkbox
3 | Weight | number
Personas y propiedades tienen muchos a muchos relación a través de una tercera PersonProperties mesa.
PersonProperties
PersonId | PropertyId | value
1 | 1 | 24
1 | 2 | true
2 | 1 | 43
Quiero filtrar las personas que tengan 20 años de edad a 30 y juega al fútbol. Como ya he ids de edad y juega al fútbol con sus valores que son Identificación del 1 (min = 20, máximo = 30) y ID 2 (verdadero). Para conseguir que consulta como esta,
SELECT `Persons`.`id`,`name` FROM `Persons`
INNER JOIN `PersonProperties` ON `Persons`.id = `PersonProperties`.`PersonId`
WHERE ((`PersonProperties`.`value` >= 20 AND `PersonProperties`.`value` <= 30) AND `PersonProperties`.`PropertyId` = 1)
AND (`PersonProperties`.`value` = true AND `PersonProperties`.`PropertyId` = 2)
GROUP BY `Persons`.`id`
Devuélvalo resultado vacío.
Resultado deseado
id | name
1 | Alex
Gordon Linoff:
Su versión no funciona, porque no hay una sola fila puede igualar ambas condiciones. Es necesario que coincidan través de las filas.
Utilice la agregación para esto:
SELECT p.id, p.name
FROM Persons p JOIN
PersonProperties pp
ON p.id = pp.PersonId
WHERE (p.PropertyId = 1 AND (p.value + 0) >= 20 AND (p.value + 0) <= 30) OR
(p.PropertyId = 2 AND p.value = 'true')
GROUP BY p.id, p.name
HAVING COUNT(*) = 2; -- both match
notas:
- Los alias de tabla hacen una consulta mucho más fácil de escribir y de leer.
- Invertidas hacen una consulta más difícil de escribir y de leer.
Value
es una cadena (presumiblemente). Por lo tanto, es necesario tener cuidado con las comparaciones. He añadido el(+ 0)
tener claro que una conversión está involucrado.