【问题标题】:mysql query join/sub-query/unionmysql 查询连接/子查询/联合
【发布时间】:2011-06-16 12:16:20
【问题描述】:

假设我的 MySQL 数据库中有两个表 - “Table1”和“Table2”。 “Table1”中的“id”主键(auto_increment)是“Table2”中的引用键-“tab_id”。

一个“Table1”行可能有零个或多个“Table2”行。

现在我正在尝试对“Table2”中的一列进行搜索,例如“email”列,或者在“Table1”中的一列中搜索“address”并打印“Table1”行值。

我看到有 3 种可能性: 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)时,查询会非常慢:(

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

【问题讨论】:

  • 不确定我是否理解您要执行的操作,但这听起来像是外部联接的工作,而不是联合。也许调查一下?

标签: mysql


【解决方案1】:
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 可用于将具有相同列的数据集合并在一起。

编辑

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

【讨论】:

  • 感谢您的回复。但是与一个简单的(如我所写的)耗时 0.13 秒相比,LEFT JOIN 大约需要 13 秒,同样的问题是,简单的 JOIN 仅在“Table2”有一个或多个引用时才有效,UNION 大约需要 0.16 秒。 “Table1”有 2600 行,“Table2”有大约 3000 行
【解决方案2】:
SELECT * 
FROM Table1 t1
   LEFT JOIN Table2 t2
      ON t1.id = t2.tab_id
WHERE t1.address like '%str%' OR t2.email like '%str%';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多