【问题标题】:Select entries by where from different tables从不同的表中选择条目
【发布时间】:2021-07-06 08:40:34
【问题描述】:

我有两张桌子:

表“数据”

 id        int(11) NOT NULL AUTO_INCREMENT,
 name      varchar(200),
 remark    varchar(200),

表格“标签”

 id        int(11) NOT NULL AUTO_INCREMENT,
 macro     varchar(200),
 value     varchar(200),
 data_id   int(11)

“data”中的一个条目可以在“tags”中有零个或多个条目,这些条目由“data_id”连接(参考“data.id”)。

现在我想从两个表中搜索带有某些 WHERE 条件的“数据”中的所有条目(在标签键/值中也匹配的条目)。

SELECT data.id,data.name 
FROM data,tags 
WHERE (data.name LIKE ?) 
   or (data.remark LIKE ?) 
   or (tags.value LIKE ?) ...

这个嵌套查询怎么做?

谢谢

【问题讨论】:

标签: sql multiple-tables


【解决方案1】:

我建议使用exists:

SELECT d.id, d.name 
FROM data d
WHERE d.name LIKE ? OR
      d.remark LIKE ? OR
      EXISTS (SELECT 1 FROM tags t WHERE t.data_id = d.id AND t.value LIKE ?);

为了性能,您需要在tags(data_id, value) 上建立索引:

CREATE INDEX idx_tag_data_id_value on tags(data_id, value);

将其表达为LEFT JOIN 相当棘手。假设每个数据只有一个标签匹配,那就是:

SELECT d.id, d.name 
FROM data d LEFT JOIN
     tags t
     ON t.data_id = d.id AND t.value LIKE ?
WHERE d.name LIKE ? OR
      d.remark LIKE ? OR
      t.data_id IS NOT NULL;

但是,如果多个标签匹配相同的数据 ID,这可能会返回重复的数据 ID。我推荐EXISTS

【讨论】:

  • 大家好,感谢您对我的问题的所有提示。 EXISTS 的想法似乎是最简单的想法,而且(使用额外的 SELECT)也是最强大的。感谢@gordon-linoff
  • 我刚刚使用示例数据库(带有随机数据)进行了尝试:aprox 1000 data 条目和 15000 tags 条目。 EXISTS 查询似乎很慢... :-(
  • @devtry 。 . .您希望索引支持EXISTS
  • “你想要一个索引”是什么意思?
  • @devtry 。 . .我已经修改了答案以指出您想要的索引。
【解决方案2】:

包含来自两个表的数据的 SQL 查询需要使用 JOIN 子句

您的查询将如下所示:

SELECT d.id, d.name 
FROM data AS d
    JOIN tags AS t ON t.data_id = d.id
WHERE (d.name LIKE ?) 
   or (d.remark LIKE ?) 
   or (t.value LIKE ?) ...

值得注意的是,这个查询将只选择至少有一个tagdata。如果您需要data,即使没有关联的tag,您也可以这样做:

SELECT d.id, d.name 
FROM data AS d
    LEFT OUTER JOIN tags AS t ON t.data_id = d.id
WHERE (d.name LIKE ?) 
   OR (d.remark LIKE ?)
   OR (t.value LIKE ?) ...

您可以在herehere 阅读更多相关信息。

【讨论】:

  • OP 正在描述left outer join 场景
  • @Stu "WHERE condition from both tables" 不会暗示INNER JOIN?无论如何,我会扩大答案。
  • 条件是or不是and
猜你喜欢
  • 2011-09-15
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2016-12-19
相关资源
最近更新 更多