我有一个配置表和一个用户表。
用户:
| id | name |
|----|----------|
| 0 | Bob |
| 1 | Ted |
| 2 | Sam |
配置:
| user_id | name | value |
|---------|----------|-------|
| 0 | a | 11 |
| 0 | b | 2 |
| 0 | c | 54 |
| 1 | a | 5 |
| 1 | b | 3 |
| 1 | c | 0 |
| 2 | a | 1 |
| 2 | b | 74 |
| 2 | c | 54 |
我以这种方式对配置进行了规范化,因为配置数量未知,但我必须根据此配置查询用户,因此无法以序列化形式存储。
我的问题是如何根据多行查找用户?例如: 选择>所有用户4和b< 5
这应该归还Bob和Ted。
答案 0 :(得分:3)
使用群组:
SELECT u.name
FROM users u
JOIN config c
ON c.user_id = u.id
GROUP BY u.name
HAVING MAX(c.name = 'a' AND c.value > 4)
AND MAX(c.name = 'b' AND c.value < 5)
使用联接:
SELECT u.name
FROM users u
JOIN config a
ON a.user_id = u.id
AND a.name = 'a'
AND a.value > 4
JOIN config b
ON b.user_id = u.id
AND b.name = 'b'
AND b.value < 5
我更喜欢JOIN
方法,因为您可以在属性后面为每个JOIN
命名并收集JOIN
中的条件。您也不必担心GROUP
会使聚合更灵活。
超过EXISTS
的奖励是,如果您需要进一步加入/计算,可以轻松访问配置属性。
答案 1 :(得分:1)
试试这个:
SELECT us.name
FROM USERS us
WHERE EXISTS (SELECT name FROM CONFIG WHERE name='a' AND value>4 AND user_id=us.id)
AND EXISTS (SELECT name FROM CONFIG WHERE name='b' AND value<5 AND user_id=us.id)
或者,您可以使用两个联接:
SELECT us.name
FROM USERS us, CONFIG c1, CONFIG c2
WHERE us.id=c1.user_id
AND c1.name='a'
AND c1.value<4
AND us.id=c2.user_id
AND c2.name='b'
AND c2.value>5
答案 2 :(得分:0)
您需要两个exists
语句:
SELECT * FROM users u
WHERE EXISTS ( SELECT 1
FROM config
WHERE user_id = u.id
AND name = 'a' AND value > 4)
AND EXISTS ( SELECT 1
FROM config
WHERE user_id = u.id
AND name = 'b' AND value < 5)
答案 3 :(得分:0)
在u.id = c.user_id中选择u.name作为u inner join config作为c,其中(c.name =&#34; a&#34;和c.value&gt; 4)或(c。 name =&#34; b&#34;和c.value&lt; 5);
答案 4 :(得分:0)
以下查询实现了结果,因为不依赖于以任何方式在表之间进行连接。 包含更多&#34; name&#34;你可以在HAVING中添加另一个OR子句。 注意:这已经在W3Schools WebSQL界面上进行了测试
SELECT
value,
name,
user_id
FROM config
GROUP BY value, name, user_id
HAVING
(
(value > 4 AND name = 'a')
OR (value < 5 AND name = 'b')
)
放弃分组后(感谢Arth)
SELECT
value,
name,
user_id
FROM config
WHERE
(
(value > 4 AND name = 'a')
OR (value < 5 AND name = 'b')
)