Sql “与”的区别是什么;“内部连接”;及;外部连接“;?
另外,Sql “与”的区别是什么;“内部连接”;及;外部连接“;?,sql,database,join,inner-join,outer-join,Sql,Database,Join,Inner Join,Outer Join,另外,左连接、右连接和完全连接如何适应?如果连接的另一侧(右侧)有匹配的记录,则内部连接仅显示行 (左)外部联接在左侧显示每条记录的行,即使联接的另一侧(右)没有匹配的行。如果没有匹配的行,则另一侧(右侧)的列将显示空值。内部联接要求联接表中存在具有相关ID的记录 外部联接将返回左侧的记录,即使右侧不存在任何记录 例如,您有一个Orders和一个OrderDetails表。它们由一个“OrderID”关联 订单 医嘱ID 客户名称 订单详细信息 OrderDetailID 医嘱ID 产品名
左连接
、右连接
和完全连接
如何适应?如果连接的另一侧(右侧)有匹配的记录,则内部连接仅显示行
(左)外部联接在左侧显示每条记录的行,即使联接的另一侧(右)没有匹配的行。如果没有匹配的行,则另一侧(右侧)的列将显示空值。内部联接要求联接表中存在具有相关ID的记录 外部联接将返回左侧的记录,即使右侧不存在任何记录 例如,您有一个Orders和一个OrderDetails表。它们由一个“OrderID”关联 订单
- 医嘱ID
- 客户名称
- OrderDetailID
- 医嘱ID
- 产品名称
- 数量
- 价格
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
将仅返回OrderDetails表中也包含某些内容的订单
如果您将其更改为外部左连接
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
LEFT JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
然后它将从Orders表返回记录,即使它们没有OrderDetails记录
通过添加where子句(如
where OrderDetails.OrderID为NULL
),您可以使用此命令查找没有任何OrderDetails指示可能孤立订单的订单,前提是您在没有重复项的列上加入,这是一种非常常见的情况:
- A和B的内部连接给出相交B的结果,即相交的内部部分
- A和B的外部连接给出了并集B的结果,即维恩图并集的外部部分
A B
- -
1 3
2 4
3 5
4 6
注意,(1,2)是A所特有的,(3,4)是常见的,(5,6)是B所特有的
内部联接
使用任何一个等价查询的内部联接都会给出两个表的交集,即它们共有的两行
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
左外连接
左外部联接将给出A中的所有行,以及B中的任何公共行
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
右外连接
右外部联接将给出B中的所有行,以及A中的任何公共行
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
完全外部联接
一个完整的外部联接将提供A和B的并集,即A中的所有行和B中的所有行。如果A中的某些内容在B中没有相应的基准,则B部分为空,反之亦然
select * from a FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
内部联接
要求在比较两个表时至少存在匹配项。例如,表A和表B表示A٨B(交叉点B)
左外连接
和左连接
是相同的。它给出了两个表中匹配的所有记录以及左表的所有可能性
类似地,右外部联接
和右联接
是相同的。它给出了两个表中匹配的所有记录以及正确表的所有可能性
SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
完全联接
是左外部联接
和右外部联接
的组合,没有重复。使用内部联接
返回两个表中匹配的所有行。i、 e.在结果表中,所有行和列都将具有值
在外部联接中,生成的表可能有空列。外部联接可以是左侧
或右侧
左外部联接
返回第一个表中的所有行,即使第二个表中没有匹配项
右外部联接
返回第二个表中的所有行,即使第一个表中没有匹配项。简单地说:
内部联接仅检索匹配的行
然而,外部联接从一个表和其他表中的所有行检索匹配的行……结果取决于您使用的是哪一行:
- 左:匹配右表中的行和左表中的所有行
- 右:匹配左表中的行和右表中的所有行或
- Full:所有表中的所有行。有没有比赛并不重要
- 在其他答案中,我看不到关于性能和优化器的太多细节
有时最好知道只有
内部联接
是关联的,这意味着优化器有最多的选项来处理它。它可以对连接顺序进行重新排序,以便更快地保持相同的结果。优化器可以使用最多的连接模式
通常,最好尝试使用内部联接
,而不是使用不同类型的联接。(当然,如果考虑到预期结果集可能的话。)
关于这种奇怪的关联行为,这里有几个很好的例子和解释:
A与B相交
SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
左外连接 选择第一个表中的所有记录,以及第二个表中的所有记录 与联接键匹配的表
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
完全外接 选择第二个表中的所有记录,以及第一个表中的所有记录 与联接键匹配的表
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
工具书类
1.Take All records from left Table
2.for(each record in right table,) {
if(Records from left & right table matching on primary & foreign key){
use their values as it is as result of join at the right side for 2nd table.
} else {
put value NULL values in that particular record as result of join at the right side for 2nd table.
}
}
employees : id , name
phone_numbers_employees : id , phone_num , emp_id
SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
--[table1] --[table2]
id | name id | name
---+------- ---+-------
1 | a1 1 | a2
2 | b1 3 | b2
SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
1 | a1 | 3 | b2
2 | b1 | 1 | a2
2 | b1 | 3 | b2
SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id
--[Results:]
id | name | id | name
-----+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
Null | Null | 3 | b2
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
INNER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
FULL OUTER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
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
empid name dept_id salary
1 Rob 1 100
2 Mark 1 300
3 John 2 100
4 Mary 2 300
5 Bill 3 700
6 Jose 6 400
deptid name
1 IT
2 Accounts
3 Security
4 HR
5 R&D
Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
6 Jose
SELECT *
FROM citizen
CROSS JOIN postalcode
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
CREATE TABLE citizen (id NUMBER,
name VARCHAR2(20),
postal NUMBER, -- <-- could do with a redesign to postalcode.id instead.
leader NUMBER);
CREATE TABLE postalcode (id NUMBER,
postal NUMBER,
city VARCHAR2(20),
area VARCHAR2(20));
INSERT INTO citizen (id, name, postal, leader)
SELECT 1, 'Smith', 2200, null FROM DUAL
UNION SELECT 2, 'Green', 31006, 1 FROM DUAL
UNION SELECT 3, 'Jensen', 623, 1 FROM DUAL;
INSERT INTO postalcode (id, postal, city, area)
SELECT 1, 2200, 'BigCity', 'Geancy' FROM DUAL
UNION SELECT 2, 31006, 'SmallTown', 'Snizkim' FROM DUAL
UNION SELECT 3, 31006, 'Settlement', 'Moon' FROM DUAL -- <-- Uuh-uhh.
UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space' FROM DUAL;
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows
SELECT *
FROM citizen c
JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
INTERSECT
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
UNION
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
OR p.area = 'Moon';
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
ORA-01790: expression must have same datatype as corresponding expression
human_name | cat_name
------------+-----------
Abe | Axel
Jen | Jellybean
Jen | Juniper
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