【问题标题】:Select from table based on values in another table in MySQL根据 MySQL 中另一个表中的值从表中选择
【发布时间】:2026-02-23 19:10:01
【问题描述】:

我在数据库中有两个简单的表

论文

ID Title                              Author 
1  A study of turtles                 Mary
2  Dietary habits of ducks            Kate
3  Similarities of turtles and cats   Fred

关键词

ID Keyword                            
1  turtles                 
2  ducks          
3  turtles
3  cats

我想选择所有具有关键字“海龟”的论文。也就是说,它会返回

ID Title                              Author 
1  A study of turtles                 Mary
3  Similarities of turtles and cats   Fred

ID Title                              Author   Keyword
1  A study of turtles                 Mary     turtles
3  Similarities of turtles and cats   Fred     turtles

我不关心是否包含关键字标题。

我认为我需要使用别名来使用选择和内连接 - 但语法不正确。

我试过了

select * from (select papers.*, keywords.* from papers inner join keywords on papers.id = keywords.id) where keyword = "turtles";

这给出了错误Every derived table must have its own alias

我已经尝试关注What is the error "Every derived table must have its own alias" in MySQL?

select * from (select papers.*, keywords.* from 
    (papers inner join keywords on papers.id = keywords.id) as T) 
    as T) 
    where keyword = "turtles";

返回语法错误。

我知道有很多类似的查询,但我是 MySQL 新手,对问题/示例感到困惑。

编辑:澄清我想从表关键字(本例中的 1 和 3)中返回与关键字“turtle”匹配的 ID,然后从论文表中选择与这些 ID 对应的行。我不想在标题中找到关键字。

【问题讨论】:

  • 不要使用相同的别名。你已经尝试改变你的表的别名了吗?
  • 对不起@dwir182 我不确定你在问什么。您能否改写您的问题 - 我对 MySQL 很陌生,所以如果我遗漏了一些明显的东西,我们深表歉意。

标签: mysql inner-join alias


【解决方案1】:

简单连接(内部):

SELECT *
FROM keywords k
JOIN papers p USING (id)
WHERE k.keyword='turtles'

【讨论】:

  • 两个表中的id 列之间不存在任何关系。
  • @TimBiegeleisen 你确定吗?关键字表包含 2 行 id 3。同样在原始问题中,两个查询都使用了该关系。
  • 这是故意的 - id 是不同记录之间的连接因素
【解决方案2】:

我们可以尝试为每篇论文的标题搜索整个关键字集,寻找匹配项。 REGEXP 运算符在这里很有帮助。特别是,我们希望将\bkeyword\b 与论文标题中的任何位置进行匹配。

SELECT p.*
FROM papers p
WHERE EXISTS (SELECT 1 FROM keywords k
              WHERE p.title REGEXP CONCAT('[[:<:]]', k.keyword, '[[:>:]]'));

Demo

编辑:

如果您只想针对单个已知关键字搜索论文标题,例如turtles,那就用这个简化:

SELECT *
FROM papers
WHERE title REGEXP '[[:<:]]turtles[[:>:]]';

【讨论】:

  • 谢谢蒂姆 - 我认为我的问题比这更简单。我只想在关键字表中找到与“turtles”(1 和 3)匹配的 ID,然后从具有这些 ID 的论文表中获取条目。我不想搜索标题中的单词(抱歉造成混淆 - 我一直对很多示例感到困惑,所以想要一些我可以轻松判断我是否正确执行的内容 - 因此有明显的关键字标题火柴)。我将更新问题以澄清这一点。
  • 如果是在查询中直接手动输入要搜索的关键字,那么关键字表在这里实际上起到什么作用?
  • 这可能不是最好的方法(我对这一切真的很陌生)-但我的意图是建立一个数据库,其中包含一个包含有关研究的关键信息的表(例如论文表),然后是一系列其他表格,其中包含有关研究的其他数据(例如关键字表 - 但还会有其他表格,例如位置、应用领域等)。每项研究可能有多个关键字,从主表中的信息中不一定很明显。然后我使用不同的查询组合在地图中生成图层。
  • 我不知道你想做什么,这在你的问题中没有出现。也许你应该告诉我们这里真正的问题是什么。
  • 我不确定什么不清楚 - 但我会再次尝试解释(尽管@kurkle 的答案对我有用,所以现在可能没有实际意义)。我想从表“keywords”中找到与关键字“turtles”相对应的 ID。然后我想从“论文”表中返回具有相同 ID 的每一行。我给出的例子是一个玩具问题——我的真实数据库会更复杂,但这是我一直在寻找的基本功能。很抱歉有任何混淆。
【解决方案3】:

我真的很喜欢Tim's的回答

这是我自己的尝试

SELECT
  *
 FROM
   papers p
   INNER JOIN keywords k ON p.`Title`  LIKE CONCAT('%', k.keyword ,'%')
  ;

SQLFiddle

正如 Tim 对此答案的评论,它将带来子字符串以及完整的单词匹配 为了解决这个问题,需要在 % 参数中添加空格

SELECT
  *
 FROM
   papers p
   INNER JOIN keywords k ON p.`Title`  LIKE CONCAT('% ', k.keyword ,' %')
  ;

【讨论】:

  • 这有一个问题,它会匹配一个关键字,该关键字恰好是标题中另一个单词的 子字符串。此外,如果给定的论文碰巧匹配多个关键字,它将返回重复项。您可以使用DISTINCT 轻松解决第二个问题。对于第一个,您需要使用REGEXP
最近更新 更多