我需要在Rails中构建一个返回具有一组特定属性的人的查询。我简化了我的榜样。所以这是两个表:
Table: people
+----+----------+
| id | name |
+----+----------+
| 1 | Person A |
| 2 | Person B |
| 3 | Person C |
+----+----------+
Table: attributes
+----+-----------+--------+--------+
| id | person_id | name | value |
+----+-----------+--------+--------+
| 1 | 1 | age | 32 |
| 2 | 1 | gender | male |
| 3 | 2 | age | 16 |
| 4 | 2 | gender | male |
| 5 | 3 | gender | female |
+----+-----------+--------+--------+
person_id
是对表people
中某人的引用。
在我的查询中,我想(例如)提出以下问题:
给我所有年龄超过25岁的男性!
name = 'gender' AND value = 'male'
和name = 'age' AND value > '25'
应返回1条记录(person_id=1)
给我所有男性或25岁以上的人!
name = 'gender' AND value = 'female'
或name = 'age' AND value > '25'
应返回2条记录(person_id=1 and 3)
示例2并不那么难。但我在示例1中遇到了问题。我不知道如何在这里处理AND
。不要忘记:WHERE
语句是动态的。意味着可以有一堆,或只有一个。
基本上我正在寻找合适的SQL语句来做到这一点。我已经玩了一点点,直到现在我做的最好的事情就是:
SELECT people.*
FROM people
INNER JOIN attributes ON attributes.person_id = people.id
WHERE
attributes.name = 'gender' AND attributes.value = 'male' OR
attributes.name = 'age' AND attributes.value > '25'
GROUP BY people.id
HAVING count(*) = 2
我不喜欢这个解决方案,因为我必须在HAVING
子句中指定匹配数。必须有一个更优雅和灵活的解决方案来做到这一点。
这是一个不复杂的例子:
SELECT people.*
FROM people
INNER JOIN attributes ON attributes.person_id = people.id
WHERE
(attributes.name = 'gender' AND attributes.value = 'male') OR
(attributes.name = 'age' AND attributes.value > '25') AND
(attributes.name = 'bodysize' AND attributes.value > '180')
GROUP BY people.id
任何想法和帮助将不胜感激。谢谢!
答案 0 :(得分:1)
考虑类似
的内容SELECT people.*
FROM people
LEFT JOIN attributes AS attr_gender
ON attr_gender.person_id = people.id
AND attr_gender.name = 'gender'
LEFT JOIN attributes AS attr_age
ON attr_age.person_id = people.id
AND attr_age.name = 'age'
结合:
1)
SELECT ...
WHERE attr_gender.value = 'male'
AND attr_age.value::int > 25
2)
SELECT ...
WHERE attr_gender.value = 'male'
OR attr_age.value::int > 25
注意:必须进行投射 - '9' > '25'
。
答案 1 :(得分:0)
你试过这个:
(attributes.name ='gender'AND attributes.value ='male')或
(attributes.name ='age'AND attributes.value> '25')
没有“GROUP BY”/“HAVING”部分?