我有两张桌子:
用户:
ID | title
0 | Adam
1 | Ben
2 | Sara
3 | Camille
users_meta:
ID | user_ID | meta_key | meta_value
0 | 0 | 'weight' | '80'
1 | 0 | 'sex' | 'male'
2 | 1 | 'weight' | '93'
3 | 1 | 'sex' | 'male'
4 | 2 | 'weight' | '57'
5 | 2 | 'sex' | 'female'
6 | 3 | 'weight' | '71'
7 | 4 | 'sex' | 'female'
现在我想让所有男性和体重都超过90的用户,我的查询:
SELECT u.* FROM users AS u
RIGHT JOIN users_meta AS weight on(u.ID=weight.user_ID)
RIGHT JOIN users_meta AS sex on(u.ID=sex.user_ID)
WHERE
weight.meta_key='weight' AND
weight.meta_key>90 AND
sex.meta_key='sex' AND
sex.meta_value ='male'
以上查询对我来说很好,但我很好奇是否有更好的方法可以做到这一点。如果每个用户都有大量的元数据,那么最终会在同一个表上使用多个联接来检查不同的值。
答案 0 :(得分:2)
您可以轻松地按users_meta
聚合user_id
表,并仅通过应用适当的HAVING
子句保留符合条件的用户ID。然后为这组所需的用户ID选择用户。
select *
from users
where user_id in
(
select user_id
from users_meta
where meta_key in ('weight', 'sex') -- not necessary, but probably faster
group by user_id
having sum(meta_key = 'weight' and meta_value > 90) > 0
and sum(meta_key = 'sex' and meta_value = 'male') > 0
);
答案 1 :(得分:1)
您可以使用单join
,例如:
SELECT DISTINCT u.id, u.title
FROM users u JOIN users_meta m ON u.id = m.user_id
WHERE (u.meta_key = 'weight' AND u.meta_value > 90)
OR (u.meta_key = 'sex' AND u.meta_value > 'male');
更新
如果你想让所有体重超过90的男性,你可以做两个join
查询,例如:
SELECT *
FROM (
SELECT id, title FROM user WHERE id in (SELECT user_ID FROM user_meta WHERE meta_key = 'weight' AND meta_value > 90)
) a JOIN (
SELECT id, title FROM user WHERE id in (SELECT user_ID FROM user_meta WHERE meta_key = 'sex' AND meta_value > 'male')
) b ON a.id = b.id;