此外,如何适应左外加入,右外加入和全外加入?
当前回答
此分類上一篇
INNER JOIN 最典型的加入为两个或多个表. 它返回数据匹配在两个表上 ON primarykey 和 forignkey 关系. OUTER JOIN 与 INNER JOIN 相同,但它还包含结果设置上的 NULL 数据. LEFT JOIN = INNER JOIN + 未匹配的左表数据与右表上的 Null 匹配. RIGHT JOIN = INNER JOIN + 未匹配的右表数据与左表上的 Null 匹配. FULL JOIN = INNER J
例如:
SELECT *
FROM tablea a
INNER JOIN tableb b
ON a.primary_key = b.foreign_key
INNER JOIN tablec c
ON b.primary_key = c.foreign_key
其他回答
我在其他答案中看不到很多关于性能和优化的细节。
有时,知道只有INNER JOIN是合并的,这意味着优化器有最多的选择与它一起玩,它可以重新订单加入顺序,使它更快地保持相同的结果,优化器可以使用最多加入模式。
一般来说,尝试使用 INNER JOIN 而不是不同类型的插件是很好的做法(当然,如果可以考虑到预期的结果设置)。
这里有几个好例子和解释这个奇怪的协会行为:
是否留在外部合并合并合并?合并命令在SQL中的内容?
一次示威
设置
跳进 psql 并创建一个小数据库的猫和人类. 你可以只是复制这个整个部分。
CREATE DATABASE catdb;
\c catdb;
\pset null '[NULL]' -- how to display null values
CREATE TABLE humans (
name text primary key
);
CREATE TABLE cats (
human_name text references humans(name),
name text
);
INSERT INTO humans (name)
VALUES ('Abe'), ('Ann'), ('Ben'), ('Jen');
INSERT INTO cats (human_name, name)
VALUES
('Abe', 'Axel'),
(NULL, 'Bitty'),
('Jen', 'Jellybean'),
('Jen', 'Juniper');
求求
SELECT
humans.name AS human_name,
cats.name AS cat_name
FROM humans
[SOMETHING JOIN] cats ON humans.name = cats.human_name
ORDER BY humans.name;
任何人,没有猫或猫,没有人,都被排除在外。
human_name | cat_name
------------+-----------
Abe | Axel
Jen | Jellybean
Jen | Juniper
A FULL OUTER JOIN returns all humans and all cats, with zero if there is no match on both sides. 全外加入将返回所有人类和所有猫,如果双方都没有比赛,则零。
human_name | cat_name
------------+-----------
Abe | Axel
Ann | [NULL]
Ben | [NULL]
Jen | Jellybean
Jen | Juniper
[NULL] | Bitty
human_name | cat_name
------------+-----------
Abe | Axel
Ann | [NULL]
Ben | [NULL]
Jen | Jellybean
Jen | Juniper
每只猫,没有人,都会在人名列中获得零;每只猫,没有人,都会被排除。
human_name | cat_name
------------+-----------
Abe | Axel
Jen | Jellybean
Jen | Juniper
[NULL] | Bitty
你可以看到,虽然一个内部加入只获得匹配夫妇,每个类型的外部加入包括一些没有比赛的项目。
加入本身意味着内部左加入,右加入和外加入,所有意味着外加入。
在内部加入中,我们可以在不同表中获取相同/相关数据的数据。
我们有三种类型的外部加入:
左加入,右加入,全加入
我们还将从左(第一)表中获取不相关的数据。
SELECT Sname, Tname FROM student s LEFT JOIN 教师 t ON s.id = t.id;
右外加入,我们还从正确的表中获取与此无关的数据(第二表)
SELECT Sname, Tname FROM student s RIGHT JOIN 教师 t ON s.id = t.id;
我们可以使用 FULL OUTER JOIN 当我们想要从两个表中获取所有 / 完整的数据时,丢失的数据将以 NULL 填写。
SELECT Sname, Tname FROM student s FULL JOIN 教师 t ON s.id = t.id;
EmpID | EmpName |
---|---|
13 | Jason |
8 | Alex |
3 | Ram |
17 | Babu |
25 | Johnson |
位置
EmpID | EmpLoc |
---|---|
13 | San Jose |
8 | Los Angeles |
3 | Pune, India |
17 | Chennai, India |
39 | Bangalore, India |
select * from employee inner join location on employee.empID = location.empID
OR
select * from employee, location where employee.empID = location.empID
Employee.EmpId | Employee.EmpName | Location.EmpId | Location.EmpLoc |
---|---|---|---|
13 | Jason | 13 | San Jose |
8 | Alex | 8 | Los Angeles |
3 | Ram | 3 | Pune, India |
17 | Babu | 17 | Chennai, India |
左外加入:- 对员工和位置表的左外加入(或仅仅是左外加入)的结果总是包含“左”表(员工)的所有记录,即使加入条件在“右”表(位置)中找不到任何匹配记录。
select * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Employee.EmpId | Employee.EmpName | Location.EmpId | Location.EmpLoc |
---|---|---|---|
13 | Jason | 13 | San Jose |
8 | Alex | 8 | Los Angeles |
3 | Ram | 3 | Pune, India |
17 | Babu | 17 | Chennai, India |
25 | Johnson | NULL | NULL |
右外登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登登
select * from employee right outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
使用上面的表,我们可以显示一个正确的外部加入的结果设置会是什么样子:
Employee.EmpId | Employee.EmpName | Location.EmpId | Location.EmpLoc |
---|---|---|---|
13 | Jason | 13 | San Jose |
8 | Alex | 8 | Los Angeles |
3 | Ram | 3 | Pune, India |
17 | Babu | 17 | Chennai, India |
NULL | NULL | 39 | Bangalore, India |
请注意,虽然没有员工被列为在巴格罗尔工作,但它仍然被列入结果中,员工字段被删除。
Employee.EmpId | Employee.EmpName | Location.EmpId | Location.EmpLoc |
---|---|---|---|
13 | Jason | 13 | San Jose |
8 | Alex | 8 | Los Angeles |
3 | Ram | 3 | Pune, India |
17 | Babu | 17 | Chennai, India |
25 | Johnson | NULL | NULL |
NULL | NULL | 39 | Bangalore, India |
Oracle 加入活动
“外部”和“内部”只是可选的元素,你只是处理两个(三个)类型的加入。内部加入(或什么是默认使用只有“加入”)是一个加入,只有符合标准的元素在两个表上存在。
“外部”插件是相同的内部插件加上不匹配的左或右表的元素,并在其他表的所有列上添加零。
全合是内合,右合和左合。
总之,如果我们有这样的表A
idA | ColumnTableA | idB |
---|---|---|
1 | Jonh | 1 |
2 | Sarah | 1 |
3 | Clark | 2 |
4 | Barbie | NULL |
图B如下:
idB | ColumnTableB |
---|---|
1 | Connor |
2 | Kent |
3 | Spock |
内部加入:
from tableA join tableB on tableA.idB = tableB.idB
idA | ColumnTableA | idB | ColumnTableB |
---|---|---|---|
1 | Jonh | 1 | Connor |
2 | Sarah | 1 | Connor |
3 | Clark | 2 | Kent |
左边加入:
from tableA left join tableB on tableA.idB = tableB.idB
idA | ColumnTableA | idB | ColumnTableB |
---|---|---|---|
1 | Jonh | 1 | Connor |
2 | Sarah | 1 | Connor |
3 | Clark | 2 | Kent |
4 | Barbie | NULL | NULL |
向外加入:
from tableA right join tableB on tableA.idB = tableB.idB
idA | ColumnTableA | idB | ColumnTableB |
---|---|---|---|
1 | Jonh | 1 | Connor |
2 | Sarah | 1 | Connor |
3 | Clark | 2 | Kent |
NULL | NULL | 3 | Spock |
全外加入:
from tableA full join tableB on tableA.idB = tableB.idB
idA | ColumnTableA | idB | ColumnTableB |
---|---|---|---|
1 | Jonh | 1 | Connor |
2 | Sarah | 1 | Connor |
3 | Clark | 2 | Kent |
4 | Barbie | NULL | NULL |
NULL | NULL | 3 | Spock |
推荐文章
- 如何在Ruby On Rails中使用NuoDB手动执行SQL命令
- 查询JSON类型内的数组元素
- 确定记录是否存在的最快方法
- 获得PostgreSQL数据库中当前连接数的正确查询
- 在SQL选择语句Order By 1的目的是什么?
- 我如何循环通过一组记录在SQL Server?
- 如何从命令行通过mysql运行一个查询?
- 外键约束可能导致循环或多条级联路径?
- 使用LIMIT/OFFSET运行查询,还可以获得总行数
- 当恢复sql时,psql无效命令\N
- 货币应该使用哪种数据类型?
- 如何选择每一行的列值不是独特的
- 如何改变字符集(和排序)在整个数据库?
- mySQL:: insert到表,数据从另一个表?
- 如何在Postgres中获得两个字段的MIN() ?