从表中选择行,其中具有相同 id 的另一个表中的行在另一列中具有特定值
Posted
技术标签:
【中文标题】从表中选择行,其中具有相同 id 的另一个表中的行在另一列中具有特定值【英文标题】:Select rows from a table where row in another table with same id has a particular value in another column 【发布时间】:2012-02-24 16:48:06 【问题描述】:在 mysql 中:
如果我们有两个表:
comments
key | value
=================
1 | foo
2 | bar
3 | foobar
4 | barfoo
和:
meta
comment_key | value
=========================
1 | 1
2 | 1
3 | 2
4 | 1
我想从comment
表中获取在meta
表中具有相应comment_key
且具有特定value
的cmets(meta
表中的value
列)。
例如,我想从comment
表中选择所有在meta
表中具有value
或1
的行:
我希望得到这些结果:
key | value
=================
1 | foo
2 | bar
4 | barfoo
如果我要从comment
表中选择所有在meta
表中具有value
或2
的行:
我希望得到这样的结果:
key | value
=================
3 | foobar
真的希望有人能帮忙,提前谢谢大家!
我想我需要加入吗?任何指针都会很棒,如果可能的话,一个简短的解释,这样我就可以找出哪里出错了 -> 下次我会知道的!
【问题讨论】:
【参考方案1】:我实际上不建议为此使用 JOIN — 或者更确切地说,我建议使用“semijoin”,这是一个不直接在 SQL 中表达的关系代数概念。半联接本质上是一种联接,您只想从一个表中检索记录,但条件是它们在不同的表中具有相应的记录。
在 SQL 表示法中,这个概念是通过使用 an IN
clause 和 subquery 间接表达的:
SELECT key, value
FROM comments
WHERE key IN
( SELECT comment_key
FROM meta
WHERE value = 1
)
;
(MySQL 实际上最终会在内部将其转换回半连接——本质上是一种退化的内连接——但IN
子句是在原始 SQL 中表达它的自然方式。)
【讨论】:
更正 - 使用join
、exists
或 in
谓词无关紧要,它们都是半连接 - 定义为基于从一个表返回行的连接另一个表中存在相关行。
@JCooper:我不这么认为。假设对于parent
中的每条记录,child
中有零个、一个或多个记录。那么半连接将包括每个parent
记录的零个或一个副本,而SQL INNER JOIN
将包括一些parent
记录的多个副本。但我可以看到你的方式。在关系代数中,半连接相当于一个内连接,然后是一个适当的投影;因此我们可以将其视为 SQL SELECT
和关系代数投影之间的差异,而不是 SQL INNER JOIN
和关系代数半连接之间的差异。
哇,我是如此接近,我只有=
而不是IN
!谢谢你,工作愉快!
我在使用 join 方法时遇到了完全相同的重复行问题。 join 不能解决重复行问题,感觉很奇怪。
这与使用简单连接但运行 distinct 以确保其唯一性相比如何?【参考方案2】:
您正在这里寻找一个普通的、普通的 equi-join。
SELECT `comment`.`key` AS `key`,
`comment`.`value` AS `value`
FROM `comments`
JOIN `meta`
ON `comments`.`key` = `meta`.`comment_key`
WHERE `meta`.`value` = 1;
我不太确定您在这里寻找什么样的建议,但您可以在 Wikipedia's SQL JOIN page. 阅读有关该主题(不是 MySQL 特定)的更多信息
我建议在 comment
.key
和 meta
.comment_key
上建立索引,假设您希望每个 comment
行只有 1 个 meta
行(PRIMARY根据定义,键是唯一的)。如果您希望每个 comment
允许超过 1 个 meta
,则将单独的索引 id
列添加到 meta
并使其成为带有 comment_key
的主键只是一个 b 树索引。
我也不确定它的性能与同样列出的“半连接”答案相比如何,但对我来说,这是表达查询的更简单、更自然的方式;不过,只有两个表,MySQL 优化起来应该不会太难。
【讨论】:
我不确定是否提及索引是否过度提出问题。我刚刚看到太多的程序员没有考虑它们,因为查询总是在测试数据上运行得很快,每个表有十几行或更少。 如果有多个子行,这不会导致父行重复吗?【参考方案3】:我会通过以下方式使用“INNER JOIN”:
SELECT comments.key, comments.value FROM comments
INNER JOIN meta ON comments.key=meta.comment_key WHERE meta.value = 1;
干杯! ;-)
【讨论】:
以上是关于从表中选择行,其中具有相同 id 的另一个表中的行在另一列中具有特定值的主要内容,如果未能解决你的问题,请参考以下文章