Sql 从不同的表中按位置选择条目
我有两张桌子: 表“数据” 表“标签” “数据”中的一个条目在“标签”中可以有零个或多个条目,这些条目通过“数据id”(参考“data.id”)连接 现在,我想从两个表中搜索“data”中具有某种WHERE条件的所有条目(在标记key/value中也匹配的条目) 如何执行此嵌套查询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
谢谢一个包含来自两个表的数据的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;