使用内部联接实现联合所有查询

Posted

技术标签:

【中文标题】使用内部联接实现联合所有查询【英文标题】:Implement a union all query with an inner join 【发布时间】:2015-08-01 20:13:00 【问题描述】:

我有 2 个这样的表:

//             table1
+-----------------+-----------------+
|       col1      |        id       |
|-----------------+-----------------|
+-----------------+-----------------+
|       test      |        1        |
|-----------------+-----------------|
|       test      |        2        |
|-----------------+-----------------|
|    anything     |        3        |
|-----------------+-----------------|
|    anything     |        4        |
|-----------------+-----------------|


//             table2
+-----------------+-----------------+
|       col1      |        id       |
|-----------------+-----------------|
+-----------------+-----------------+
|       test      |        5        |
|-----------------+-----------------|
|       test      |        6        |
|-----------------+-----------------|
|    anything     |        7        |
|-----------------+-----------------|
|    anything     |        8        |
|-----------------+-----------------|

当我使用union all 获取id 值时col1 等于“测试”时,需要结果:

select * from table1 where col1='test'
union all
select * from table2 where col1='test'

// the result of this code is: 4 rows. id1,2,5,6

然后,为了更快更好的性能,我使用inner join 实现了它,但结果并不理想:

select * from table1 t1 inner join table2 t2
on t1.col1=t2.col1
where t1.col1='test'

// the result of this code is: 8 rows. id1-5,1-6,2-5,2-6

如何在这些表中使用inner join 来获取结果 id1、2、5、6?


编辑

示例:

table1 [col1]=word, [col2]=mean
+-----+------------------------------------------------------------------------------------------+
|  a  | used when referring to someone or something for the first time in a text or conversation |
|-----|------------------------------------------------------------------------------------------|
|  a  | used to indicate membership of a class of people or things                               |
|-----|------------------------------------------------------------------------------------------|
|  x  | xxxxx                                                                                    |
+-----+------------------------------------------------------------------------------------------+

table2 [col1]=word, [col2]=mean
+-----+------------------------------------------------------------------------------------------+
|  a  | the blood group whose red cells carry the A antigen                                      |
|-----|------------------------------------------------------------------------------------------|
|  x  | xxxxx                                                                                    |
+-----+------------------------------------------------------------------------------------------+

现在我可以使用joinecho 这个吗? :

a | used when referring to someone or something for the first time in a text or conversation
a | used to indicate membership of a class of people or things
a | the blood group whose red cells carry the A antigen 

【问题讨论】:

如果您需要始终将它们视为“假单曲”,将这些表格组合成一个表格不是更容易吗? @MarcB 什么???当我使用inner join 而不是union all 时,搜索速度会提高! 为什么我要问,让single_table 拥有两个表中的数据,而不是两个单独的表,你需要将它们与查询结合起来,这不是更聪明吗? 8 行 ?连接自然会将行彼此相邻,您应该有 4 行和 4 列 @MarcB 啊哈,这是一个例子,事实上我有 5 个表,每个表都有超过 300,000 行。我无法创建一张表。 【参考方案1】:

使用内部连接无法轻松做到这一点。考虑一下内部连接的作用,它根据相关列将它们彼此相邻。例如,如果您运行以下查询:

SELECT *
FROM table1
JOIN table2 ON table2.col1 = table1.col1 AND table2.col1 = 'test';

你会看到这样的结果:

| col1 | id | col1 | id |
+------+----+------+----+
| test | 1  | test | 5  |
| test | 2  | test | 5  |
| test | 1  | test | 6  |
| test | 2  | test | 6  |

此时,您可能会尝试从两列中的每一列运行不同值的查询,但据我所知,这是不可能的。

所以,我不相信您可以将 UNION ALL 查询替换为 INNER JOIN,或任何与此相关的连接。即使您执行了交叉连接,您也只会在自己的列中获得table1.id,而在单独的列中获得table2.id,这会导致与上述相同的问题。


编辑

当您使用union all 时,您只是在组合表格中的行。因此,如果我运行以下查询:

SELECT col1, id
FROM table1
WHERE col1 = 'test'
UNION ALL
SELECT col1, id
FROM table2
WHERE col1 = 'test'

你会看到这个:

| col1 | id |
+------+----+
| test | 1  |
| test | 2  |
| test | 5  |
| test | 6  |

因为它从两个单独的查询中获取结果集并将它们组合在一起。这是一个 SQL Fiddle 示例,它显示了两个查询,因此您可以直观地看到并排的差异。

【讨论】:

啊哈,我明白了,可以编辑你的答案并告诉我什么时候使用 union all what table made?​​span> 哇,这是一个完美的描述。那我根本不能使用加入?!事实上,我有一个字典网站,我有 5 个英文单词来源(5 个表)。然后用户在 5 表中搜索,将看到 5 表的结果。我如何在 5 个表中搜索一个单词? @stack 按照上面看到的相同模式'SELECT englishWords UNION ALL SELECT spanishWords UNION ALL selectFrenchWords...',您可以在一个语句中使用多个UNION ALL 好像我必须使用UNION ALL。但是join 非常快 :(( 无论如何,谢谢 @stack 没问题。如果您重新考虑如何显示数据,我可以看到您使用JOIN 的唯一方法是也许。如果您愿意并排查看不同的语言而不是所有语言都在一个列中,但这也很棘手。

以上是关于使用内部联接实现联合所有查询的主要内容,如果未能解决你的问题,请参考以下文章

忽略单峰的内部联接

使用内部联接获取一个月的所有周数据

尝试合并包含联接操作的 2 个子查询时,BigQuery 联合失败

SQL Server-交叉联接内部联接基础回顾

使用内部联接删除

SQL Server 2005 - 内部联接的顺序