说我在MySQL数据库中有两个表 - “Table1”和“Table2”。 “Table1”中的“id”主键(auto_increment)是“Table2” - “tab_id”中的引用键。
一个“Table1”行可能有零个或多个“Table2”行。
现在我正在尝试搜索“Table2”中的一列,说“email”列或“Table1”中的一列上的“地址”,并打印“Table1”行值。
我看到有三种可能性: 加入 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
答案 0 :(得分:2)
SELECT *
FROM Table1 t1
LEFT JOIN Table t2 ON t2.tab_id = t1.id
WHERE t1.address like '%str%'
OR t2.email like '%str%';
您需要执行LEFT JOIN
。当您从两个表中创建FROM
时,它将作为INNER JOIN
(如果没有WHERE子句则为CROSS JOIN),这意味着输出仅显示具有匹配项的行在两个表中。对于LEFT JOIN
,您说您希望左表(t1)中的所有行与右表(t2)上的匹配行。如果t2中没有匹配项,则使用null
。
您可以使用子查询,但正如您所看到的那样,它不是最佳选择
UNION
这里没有任何优势。 UNION
可用于将具有相同列的数据集合并在一起。
修改强>
如果您遇到JOIN问题,因为某些Table1行没有出现,那么您需要LEFT JOIN。需要很长时间的事实是另一个问题。那些表格根本不大,所以我猜你需要对这些表做一些索引工作。
如果您需要有关union
的帮助,您需要告诉我哪些是relevant_columns
,因为它们必须具有相同数量的列,相同类型和相同的序列。
您可以在不加入的情况下优化union
,具体取决于t2.email
匹配时您要输出的内容。这是一个例子
SELECT t1.id, t1.address, null as email
FROM Table1 t1
WHERE t1.address like '%str%'
union
SELECT t2.tab_id as id, null as address, t2.email
FROM Table t2
WHERE t2.email like '%str%';
答案 1 :(得分:1)
SELECT *
FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.id = t2.tab_id
WHERE t1.address like '%str%' OR t2.email like '%str%';