网站首页 > 基础教程 正文
本文从笛卡尔积出发,
介绍SQL在 join 时数据是怎样组合和筛选来获得结果的,
帮助你理清join、left join、right join、full join等各类不同join的差异。
笛卡尔积
首先,让我们了解一下join中涉及到的重要概念,笛卡尔积。
两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X × Y,是第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员 。
现在,我们有两个集合A和B。
A = {0,1} ,B = {2,3,4}
集合 A×B 和 B×A的结果集就可以分别表示为以下这种形式:
A×B = {(0,2),(1,2),(0,3),(1,3),(0,4),(1,4)};
B×A = {(2,0),(2,1),(3,0),(3,1),(4,0),(4,1)};
以上A×B和B×A的结果就可以叫做两个集合相乘的‘笛卡尔积’。
从以上的数据分析我们可以得出以下两点结论:
1,两个集合相乘,不满足交换率,既 A×B ≠ B×A;
2,A集合和B集合相乘,包含了集合A中元素和集合B中元素相结合的所有的可能性。既两个集合相乘得到的新集合的元素个数是 A集合的元素个数 × B集合的元素个数。
jon解析
假设,我们有table_a和table_b两个表,如图所示。
接下来,我们看一下不同类型的 join下,到底发生了什么。
1. Inner Join / Join
select * from table_a a join table_b b on a.id = b.id;
首先,我们分别为table_a与table_b添加一个空行,
接下来,作出table_a’和table_b’的笛卡尔积,
最后一步就非常简单了,就是筛选出上表中满足on条件的部分,即id_a = id_b,
可能有同学奇怪,为什么id_a 、 id_b均为NULL的数据为什么没有被选出呢?
这是因为在SQL中,null代表什么都不是,用“=、>、< ...” 所有的判断,结果都是false。
2. Left Join
select * from table_a a left join table_b b on a.id = b.id;
首先,仍然是为table_a与table_b添加一个空行,并做笛卡尔积,
但最后一步中,我们不仅筛选出符合id_a = id_b条件的数据,还会筛选出table_a’未关联到table_b’的数据。
2. Right Join
select * from table_a a right join table_b b on a.id = b.id;
与left join类似,做出笛卡尔积后,筛选出符合id_a = id_b条件的数据,和table_b’未关联到table_a’的数据。
2. Full Join
select * from table_a a full join table_b b on a.id = b.id;
full join的结果为left join、right join的并集,
做出笛卡尔积后,筛选出符合id_a = id_b条件的数据、table_a’未关联到table_b’的数据和table_b’未关联到table_a’的数据。
猜你喜欢
- 2024-10-11 SQL语法——右连接 RIGHT JOIN 关键字
- 2024-10-11 数据筛选,如何像SQL一样使用Pandas完成JOIN连接、UNION合并查询
- 2024-10-11 SQL多个Join on 和Where间的执行顺序(nest loop join机制)
- 2024-10-11 SparkSQL大数据实战:揭开Join的神秘面纱
- 2024-10-11 SQL INNER JOIN 关键字 sql关键字union
- 2024-10-11 阿里规范不建议多表join,可这SQL要怎么写
- 2024-10-11 SQL RIGHT JOIN 关键字 sql语句 关键字
- 2024-10-11 Apache Flink 漫谈系列-JOIN 算子
- 2024-10-11 awk实现类sql的join操作 awvs结合sqlmap
- 2024-10-11 扩展FlinkSQL实现流与维表Join flinksql mysql维表
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)