Sql 从不同的表中按位置选择条目

Sql 从不同的表中按位置选择条目,sql,multiple-tables,Sql,Multiple Tables,我有两张桌子: 表“数据” 表“标签” “数据”中的一个条目在“标签”中可以有零个或多个条目,这些条目通过“数据id”(参考“data.id”)连接 现在,我想从两个表中搜索“data”中具有某种WHERE条件的所有条目(在标记key/value中也匹配的条目) 如何执行此嵌套查询 谢谢一个包含来自两个表的数据的SQL查询需要使用一个JOIN子句 您的查询将如下所示: SELECT d.id, d.name FROM data AS d JOIN tags AS t ON t.data

我有两张桌子:

表“数据”

表“标签”

“数据”中的一个条目在“标签”中可以有零个或多个条目,这些条目通过“数据id”(参考“data.id”)连接

现在,我想从两个表中搜索“data”中具有某种WHERE条件的所有条目(在标记key/value中也匹配的条目)

如何执行此嵌套查询


谢谢

一个包含来自两个表的数据的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 ?) ...
值得注意的是,此查询将仅选择至少有一个
标记的
数据
。如果您需要
数据
,即使没有相关的
标记
,您也可以执行以下操作:

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 ?) ...

您可以阅读更多关于它的信息。

我建议使用
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 ?);
为了提高性能,您需要在
标记(数据\u id,值)
上建立索引:

将其表示为
左连接是相当棘手的。假设每个数据只匹配一个标记,则为:

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。我建议
存在

您不要解释为什么结果不是您期望的结果…请提供示例数据和所需结果。OP描述的是一个
左外连接
scenario@Stu
“两个表中的WHERE条件”
是否意味着一个
内部联接?不管怎样,我将扩展答案。条件是
不是
大家好,谢谢所有关于我问题的提示。使用EXISTS的想法似乎是最简单的,而且(使用额外的SELECT)也是最强大的。多亏了@gordon linoffI,我刚刚用一个样本数据库(随机数据)尝试了这一点:大约1000个
数据
条目和15000个
标签
条目。
存在
查询似乎非常慢…:-(@devtry…你想要一个索引来支持
存在
。“你想要一个索引”是什么意思?@devtry…我已经修改了答案,指出了你想要的索引。
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 ?) ...
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 ?);
CREATE INDEX idx_tag_data_id_value on tags(data_id, value);
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;