说我在MySQL数据库中有两个表 - “Table1”和“Table2” . “Table1”中的“id”主键(auto_increment)是“Table2” - “tab_id”中的引用键 .
一个“Table1”行可能有零个或多个“Table2”行 .
现在我正在尝试搜索“Table2”中的一列,说“email”列或“Table1”中的一列上的“地址”并打印“Table1”行值 .
我看到有三种可能性:1 . 加入2.子查询3.联盟
1加入
SELECT *
FROM Table1 t1, Table t2
WHERE t1.id = t2.tab_id
AND (t1.address like '%str%' OR t2.email like '%str%');
- 这样可以正常工作,但是当“Table2”中没有与“Table1”相关的行时...... JOIN将失败,因此输出不一致 .
2子查询
SELECT *
FROM Table1 t1
WHERE t1.address like '%str%'
OR t1.id IN (SELECT t2.tab_id
FROM Table2 t2
WHERE t2.email like '%str%');
- 这工作正常,但当“Table2”(比如5K)中有两个manys行时,查询变得很慢:(
3联盟
SELECT 'relevant_columns'
FROM Table1 t1, Table t2
WHERE t1.id = t2.tab_id
AND (t1.address like '%str%' OR t2.email like '%str%')
UNION
SELECT 'relevant_columns'
FROM Table1 t1
WHERE t1.address like '%str%'
ORDER BY relevant_column
- 这工作正常,可能会创建一个类似UNION的视图,完成工作 .
现在,我的问题是什么是正确的方法......是否可以永远呼叫UNION?
MySQL引擎:MyISAM
2 回答
你需要做一个
LEFT JOIN
. 当您从两个表中创建FROM
时,它将作为INNER JOIN
(如果没有WHERE子句则为CROSS JOIN),这意味着输出仅显示两个表中都匹配的行 . 对于LEFT JOIN
,您说您希望左表(t1)中的所有行与右表(t2)上的匹配行 . 如果t2中没有匹配,则使用null
.您可以使用子查询,但正如您所看到的那样,它不是最佳选择
UNION
这里没有给你任何好处 .UNION
可用于将具有相同列的数据集合并在一起 .Edit
如果您遇到JOIN问题,因为某些Table1行没有出现,那么您需要LEFT JOIN . 需要很长时间的事实是另一个问题 . 那些表格并不大,所以我猜你需要对这些表做一些索引工作 .
如果您需要有关
union
的帮助,您需要告诉我哪些是relevant_columns
,因为它们必须具有相同数量的列,相同类型和相同的序列 . 您可以在没有连接的情况下优化union
,具体取决于t2.email
匹配时要输出的内容 . 这是一个例子