此外,如何适应左外加入,右外加入和全外加入?
当前回答
加入更容易用一个例子来解释:
此分類上一篇
模拟在单独的表中存储的人和电子邮件,
表 A 和表 B 由表_A.id = 表_B.name_id 添加
内部加入
此分類上一篇
只显示相匹配的IDS行。
外面加入
此分類上一篇
表 A 的匹配 ID 和不匹配行显示。
此分類上一篇
显示表 B 的匹配 ID 和不匹配行。
相匹配的ID和不相匹配的行从两个表显示。
注意:在 MySQL 上不存在完整的外部加入
其他回答
一次示威
设置
跳进 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
你可以看到,虽然一个内部加入只获得匹配夫妇,每个类型的外部加入包括一些没有比赛的项目。
加入本身意味着内部左加入,右加入和外加入,所有意味着外加入。
这里有很多很好的答案,非常准确的相对 algebra 例子. 这里是一个非常简单的答案,这可能有助于爱好者或初学者编码器与 SQL 编码 dilemmas。
基本上,更常见的是,JOIN询问会分为两个案例:
对于一个数据组的选项:
使用 INNER JOIN 当您正在寻找的相关 B 数据必须根据数据库设计存在;使用 LEFT JOIN 当您正在寻找的相关 B 数据 MIGHT 或 MIGHT NOT 根据数据库设计存在。
简单的说法:
一个内部合并只接收相匹配的行列。
虽然一个外部加入从一个表中获取相匹配的行,而在另一个表中的所有行......结果取决于你使用哪个行:
左: 右桌上的匹配行和左桌上的所有行 右: 左桌上的匹配行和右桌上的所有行 或 完整: 所有桌上的所有行。
这些两个表构成了下面的 JOIN 代表性的基础:
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
INNER JOIN成为一个卡特西亚产品,它与The General Idea/CROSS JOIN相同:
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';
...并给出结果:
此外,这里有一个Venn图表有意义:
此分類上一篇
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
试图将结果与联合会相结合,提供一个
ORA-01790: expression must have same datatype as corresponding expression
批评了我非常喜欢的红色阴影的Venn图表,我认为发表我自己的尝试是公平的。
虽然 @Martin Smith 的答案在很长一段时间内是这个集合中最好的,但他的单一显示每个桌子的关键列,而我认为理想的非关键列也应该显示。
在允许的半小时内我能做的最好,我仍然不认为它足够地表明,由于TableB中缺乏关键值,零值存在,或者外加入实际上是一个联盟而不是一个联盟:
此分類上一篇
推荐文章
- 如何在Ruby On Rails中使用NuoDB手动执行SQL命令
- 查询JSON类型内的数组元素
- 确定记录是否存在的最快方法
- 获得PostgreSQL数据库中当前连接数的正确查询
- 在SQL选择语句Order By 1的目的是什么?
- 我如何循环通过一组记录在SQL Server?
- 如何从命令行通过mysql运行一个查询?
- 外键约束可能导致循环或多条级联路径?
- 使用LIMIT/OFFSET运行查询,还可以获得总行数
- 当恢复sql时,psql无效命令\N
- 货币应该使用哪种数据类型?
- 如何选择每一行的列值不是独特的
- 如何改变字符集(和排序)在整个数据库?
- mySQL:: insert到表,数据从另一个表?
- 如何在Postgres中获得两个字段的MIN() ?