"SELECT .. WHERE .. AND .."(两个条件)对于键值table?
"SELECT .. WHERE .. AND .." (two conditions) for a key-value table?
我想做什么
我试图通过询问 type = x
和 target = x
,
来获得 commentId
通常(这是一个示例),table 的结构应该如下所示:
+-----------+-------+--------+
| commentId | type | target |
+-----------+-------+--------+
| 1 | post | 2 |
| 2 | post | 8 |
| 3 | video | 6 |
+-----------+-------+--------+
在这种情况下,我可以使用此查询来获取 commentId
:
SELECT `commentId` FROM `comment_datas` WHERE type = 'post' AND target = '2'
真正的问题
但是这是table的真实结构(使用key-value设计):
+-----------+--------+-------+
| commentId | name | value |
+-----------+--------+-------+
| 1 | type | post |
| 1 | target | 2 |
| 2 | type | post |
| 2 | target | 8 |
| 3 | type | post |
| 3 | target | 6 |
+-----------+--------+-------+
现在我不知道如何通过上面写的查询得到 commentId
,有什么想法吗?
按 commentId
分组。然后你可以过滤那些至少有一个记录的组,你想要的条件
SELECT commentId
FROM comment_datas
GROUP BY commentId
HAVING sum(name = 'type' and value = 'post') > 0
AND sum(name = 'target' and value = '2') > 0
您需要 select 值数字和子 select 类型或其他方式。
类似
SELECT commentId FROM comment_datas
WHERE name="type" AND value="post"
AND commentId IN (
SELECT commentId FROM comment_datas WHERE name="target" AND value=2
);
但严重的是,如果您这样离开架构,您将 运行 更频繁地陷入此类问题。你基本上有两行而不是一行。
而不是 "name" 和 "value" 更好地使用实际名称和值作为列名称和值。因此删除 "name" 和 "value",并添加 "type" 和 "target" 作为列。这样您就不会重复输入,并且可以使 ID 唯一。您当前的架构将键值系统置于键值系统之上。
用户这个,你会得到两条记录
SELECT `commentId` FROM `comment_datas ` WHERE (name = 'type' AND value = 'post') OR (name = 'target' AND value = '2') GROUP BY `commentId`
试试这个,
SELECT
`commentId`
FROM
`comment_datas`
WHERE
(`name` = 'type' AND `value` = 'post') OR
(`name` = 'target' AND `value` = '2')
GROUP BY
`commentId`
直到@juergen-d 修正了他的打字错误:这里是更正后的版本:
SELECT commentId
FROM comment_datas
GROUP BY commentId
HAVING sum(name = 'type' AND value = 'post') > 0
AND sum(name = 'target' AND value = '2') > 0
解释:
sum
除列名外还接受聚合表达式,因此我们的想法是将条目与 name = type
和 value = post
相加
通过使 sum
大于 0,select returns 只有 group by
中满足聚合表达式的行 - target
也是如此。
我想做什么
我试图通过询问 type = x
和 target = x
,
commentId
通常(这是一个示例),table 的结构应该如下所示:
+-----------+-------+--------+
| commentId | type | target |
+-----------+-------+--------+
| 1 | post | 2 |
| 2 | post | 8 |
| 3 | video | 6 |
+-----------+-------+--------+
在这种情况下,我可以使用此查询来获取 commentId
:
SELECT `commentId` FROM `comment_datas` WHERE type = 'post' AND target = '2'
真正的问题
但是这是table的真实结构(使用key-value设计):
+-----------+--------+-------+
| commentId | name | value |
+-----------+--------+-------+
| 1 | type | post |
| 1 | target | 2 |
| 2 | type | post |
| 2 | target | 8 |
| 3 | type | post |
| 3 | target | 6 |
+-----------+--------+-------+
现在我不知道如何通过上面写的查询得到 commentId
,有什么想法吗?
按 commentId
分组。然后你可以过滤那些至少有一个记录的组,你想要的条件
SELECT commentId
FROM comment_datas
GROUP BY commentId
HAVING sum(name = 'type' and value = 'post') > 0
AND sum(name = 'target' and value = '2') > 0
您需要 select 值数字和子 select 类型或其他方式。
类似
SELECT commentId FROM comment_datas
WHERE name="type" AND value="post"
AND commentId IN (
SELECT commentId FROM comment_datas WHERE name="target" AND value=2
);
但严重的是,如果您这样离开架构,您将 运行 更频繁地陷入此类问题。你基本上有两行而不是一行。
而不是 "name" 和 "value" 更好地使用实际名称和值作为列名称和值。因此删除 "name" 和 "value",并添加 "type" 和 "target" 作为列。这样您就不会重复输入,并且可以使 ID 唯一。您当前的架构将键值系统置于键值系统之上。
用户这个,你会得到两条记录
SELECT `commentId` FROM `comment_datas ` WHERE (name = 'type' AND value = 'post') OR (name = 'target' AND value = '2') GROUP BY `commentId`
试试这个,
SELECT
`commentId`
FROM
`comment_datas`
WHERE
(`name` = 'type' AND `value` = 'post') OR
(`name` = 'target' AND `value` = '2')
GROUP BY
`commentId`
直到@juergen-d 修正了他的打字错误:这里是更正后的版本:
SELECT commentId
FROM comment_datas
GROUP BY commentId
HAVING sum(name = 'type' AND value = 'post') > 0
AND sum(name = 'target' AND value = '2') > 0
解释:
sum
除列名外还接受聚合表达式,因此我们的想法是将条目与 name = type
和 value = post
相加
通过使 sum
大于 0,select returns 只有 group by
中满足聚合表达式的行 - target
也是如此。