mysql查询join / sub-query / union

时间:2011-06-16 12:16:20

标签: mysql

说我在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

2 个答案:

答案 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%';
  1. 您需要执行LEFT JOIN。当您从两个表中创建FROM时,它将作为INNER JOIN(如果没有WHERE子句则为CROSS JOIN),这意味着输出仅显示具有匹配项的行在两个表中。对于LEFT JOIN,您说您希望左表(t1)中的所有行与右表(t2)上的匹配行。如果t2中没有匹配项,则使用null

  2. 您可以使用子查询,但正如您所看到的那样,它不是最佳选择

  3. UNION这里没有任何优势。 UNION可用于将具有相同列的数据集合并在一起。

  4. 修改

    如果您遇到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%';