PostgreSQL JOIN 多表查询 TP框架实现Excel批量导入数据库数据 MySQL中的列转行 这次是真拯救了我,MySQL索引优化,explain讲得非常清楚了 Oracle快速入门(PLSQL编程) MySQL字符串拼接、截取 MySQL事务管理及存储引擎 《浪姐》万茜点赞宁静、郁可唯黑贴坐实?盗号者和程序员是背锅侠 程序员被公司辞退12天后,前领导要求回公司讲清代码,结果懵了 易语言大漠多线程foobar在游戏多窗口中时时显示输出信息 非科班,自学两年,复盘两个月,侥幸拿到头条、阿里offer 2020年全国数学建模大赛B题源代码以及模型的建立 (2) 2020年数学建模-校园供水系统智能管理 windows破解锁屏密码(亲测有效:再也不怕别人锁屏防你啦!) 清华大佬力荐的JVM学习路线+实战笔记+阿里真题,嚼碎吃透吊打面试官 打造多模块+高可用+高扩展Spring Cloud版分布式电商项目源码分享 Python爬虫入门教程 89-100 定个小目标,先用Python爬个一亿B站用户 五大分布式事务,你了解多少? 2020-09-12 九大核心专题,630页内容,熬夜23天吃透,我收割了3个大厂offer 防抖节流 防抖和节流 函数节流 debounce throttle 每天补充一点 一些零碎的小知识点 JavaScript作用域和作用域链知多少 01-jquery概述 简单概述JSONP原理 02-$符号-jquery与js相互转换 遇见 vue.js --------阿文的vue.js学习笔记(2)----- 基本使用 全国鞋服行业首个5G专项应用落地柒牌 自动搬运作业提升效率150% 大数据系统提高生产效率超10% [网络安全自学篇] 九十四.《Windows黑客编程技术详解》之提权技术(令牌权限提升和Bypass UAC) 鸿蒙OS 2.0 开源蹭热浅读 蚂蚁三面滑铁卢!遭分布式截胡,靠这些笔记潜修30天,挺进京东 【高并发】Redis如何助力高并发秒杀系统,看完这篇我彻底懂了!! K8s概述:几种集群方案的对比 Linux到底该怎么学?RHCA架构师整理了300页学习笔记 到了2020年,技术水平到底需要达到怎样的程度才能成为顶级的阿里P8架构师 Linux怎么学?一张思维导图带你深入Linux核心原理 金九银十首战告捷!凭借这份Alibaba爆款“面试宝典”成功斩获美团Offer 大数据杀熟:我投之以元宝,它报之以砍刀! “物联网加持”下的社区长啥样儿? 潘云鹤院士:大数据智能是人工智能2.0的核心组成部分 防小孩和老人走失,定位精度达1厘米?上海社区为先进物联网产品提供落地场景 技术老兵十年专攻MySQL编写了763页核心总结,90MySQL问题全解 【Jenkins自动化部署】Windows节点Apache+Django服务自动化构建 Mybatis 使用通用 mapper 正道的光!阿里爆款Jenkins+K8s笔记终于全网开源了 不要死磕Java并发了,阿里P7架构师带你深入剖析synchronized的实现原理 EtherNet/IP协议基础知识(Part 1) CGB2005-京淘13 思科 OSPF协议简单配置与分析 在一家公司呆了 10 年的程序员,最后都怎么了?
您的位置:首页 >程序人生 >

PostgreSQL JOIN 多表查询

JOIN用于多张表的关联查询,如SELECT子句(SELECT A.a,A.b,B.a,B.d)中既有表A的字段,同时还有B表的字段,此时使用单独使用FROM A或FROM B已经解决不了问题了,使用JOIN来关联表A和表B即可解决问题,即FROM A,B或A JOIN B,这种方式得到的结果其实是表A与表B的笛卡尔积,即如果A是M1行,N1列的表,B是M2行,N2列的表,A JOIN B的结果是(M1*M2)行,(N1+N2)列的结果集。JOIN可以是等值连接(A JOIN B ON (A.a=B.c)),也可以是非等值连接(即大于,小于等,如A JOIN B ON(A.a > B.c)),也可以不使用任何条件JOIN,即笛卡尔积,但是非等值连接和笛卡尔积实际意义不大,特别是还存在性能问题。

 

测试表:

create table tbl_course(course_id bigint not null primary key,course_name varchar(12) not null);create table tbl_student(stu_id bigint not null,stu_name varchar(12),constraint pk_tbl_student_stu_id primary key(stu_id));create table tbl_student_course(stu_id bigint not null,course_id bigint not null,constraint pk_tbl_student_course_stu_id_course_id primary key(stu_id,course_id),constraint fk_tbl_student_course_stu_id foreign key(stu_id) references tbl_student(stu_id) ,constraint fk_tbl_student_course_course_id foreign key(course_id) references tbl_course(course_id));
test=# insert into tbl_course values(1,'高等数学'),(2,'大学英语'),(3,'大学物理'),(4,'电影欣赏');INSERT 0 4test=# insert into tbl_student values(1,'张三'),(2,'李四'),(3,'王五'),(4,'麻子');INSERT 0 4test=# insert into tbl_student_course values (1,2),(1,4),(2,4),(3,4);INSERT 0 4

一.笛卡尔积

示例.笛卡尔积确实没什么实际意义,测试表中其实只有4个选课数据。

test=# select * from tbl_course ,tbl_student,tbl_student_course; course_id | course_name | stu_id | stu_name | stu_id | course_id -----------+-------------+--------+----------+--------+----------- 1 | 高等数学|1 | 张三 |1 | 2 1 | 高等数学|1 | 张三 |1 | 4 1 | 高等数学|1 | 张三 |2 | 4 1 | 高等数学|1 | 张三 |3 | 4 1 | 高等数学|2 | 李四 |1 | 2 1 | 高等数学|2 | 李四 |1 | 4 1 | 高等数学|2 | 李四 |2 | 4 1 | 高等数学|2 | 李四 |3 | 4 1 | 高等数学|3 | 王五 |1 | 2 1 | 高等数学|3 | 王五 |1 | 4 1 | 高等数学|3 | 王五 |2 | 4 1 | 高等数学|3 | 王五 |3 | 4 1 | 高等数学|4 | 麻子 |1 | 2 1 | 高等数学|4 | 麻子 |1 | 4 1 | 高等数学|4 | 麻子 |2 | 4 1 | 高等数学|4 | 麻子 |3 | 4 2 | 大学英语|1 | 张三 |1 | 2 2 | 大学英语|1 | 张三 |1 | 4 2 | 大学英语|1 | 张三 |2 | 4 2 | 大学英语|1 | 张三 |3 | 4 2 | 大学英语|2 | 李四 |1 | 2 2 | 大学英语|2 | 李四 |1 | 4 2 | 大学英语|2 | 李四 |2 | 4 2 | 大学英语|2 | 李四 |3 | 4 2 | 大学英语|3 | 王五 |1 | 2 2 | 大学英语|3 | 王五 |1 | 4 2 | 大学英语|3 | 王五 |2 | 4 2 | 大学英语|3 | 王五 |3 | 4 2 | 大学英语|4 | 麻子 |1 | 2 2 | 大学英语|4 | 麻子 |1 | 4 2 | 大学英语|4 | 麻子 |2 | 4 2 | 大学英语|4 | 麻子 |3 | 4 3 | 大学物理|1 | 张三 |1 | 2 3 | 大学物理|1 | 张三 |1 | 4 3 | 大学物理|1 | 张三 |2 | 4 3 | 大学物理|1 | 张三 |3 | 4 3 | 大学物理|2 | 李四 |1 | 2 3 | 大学物理|2 | 李四 |1 | 4 3 | 大学物理|2 | 李四 |2 | 4 3 | 大学物理|2 | 李四 |3 | 4 3 | 大学物理|3 | 王五 |1 | 2 3 | 大学物理|3 | 王五 |1 | 4 3 | 大学物理|3 | 王五 |2 | 4 3 | 大学物理|3 | 王五 |3 | 4 3 | 大学物理|4 | 麻子 |1 | 2 3 | 大学物理|4 | 麻子 |1 | 4 3 | 大学物理|4 | 麻子 |2 | 4 3 | 大学物理|4 | 麻子 |3 | 4 4 | 电影欣赏|1 | 张三 |1 | 2 4 | 电影欣赏|1 | 张三 |1 | 4 4 | 电影欣赏|1 | 张三 |2 | 4 4 | 电影欣赏|1 | 张三 |3 | 4 4 | 电影欣赏|2 | 李四 |1 | 2 4 | 电影欣赏|2 | 李四 |1 | 4 4 | 电影欣赏|2 | 李四 |2 | 4 4 | 电影欣赏|2 | 李四 |3 | 4 4 | 电影欣赏|3 | 王五 |1 | 2 4 | 电影欣赏|3 | 王五 |1 | 4 4 | 电影欣赏|3 | 王五 |2 | 4 4 | 电影欣赏|3 | 王五 |3 | 4 4 | 电影欣赏|4 | 麻子 |1 | 2 4 | 电影欣赏|4 | 麻子 |1 | 4 4 | 电影欣赏|4 | 麻子 |2 | 4 4 | 电影欣赏|4 | 麻子 |3 | 4(64 rows)

JOIN连接分为内连接和外连接,而外连接又分为左外连接,右外连接,全外连接。

二.内连接

INNER JOIN,其中INNER可以省略。

语法:

A INNER JOIN B ON (A.a = B.b)

如果ON条件中两张表的字段名称相同,还可以简单一点

A INNER JOIN B USING(a = b)

内连接的结果如下图中红色部分

 

示例:查询选课情况

test=# select * from tbl_student_course join tbl_student using(stu_id) join tbl_course using(course_id); course_id | stu_id | stu_name | course_name -----------+--------+----------+------------- 2 |1 | 张三 | 大学英语 4 |1 | 张三 | 电影欣赏 4 |2 | 李四 | 电影欣赏 4 |3 | 王五 | 电影欣赏(4 rows)

 

三.左外连接(LEFT JOIN / LEFT OUTER JOIN)

左外连接其实是一个内连接然后加上左表独有的数据行,结果集中右表的字段自动补充NULL。

LEFT OUTER JOIN ,其中OUTER可以省略。

语法:

A LEFT JOIN B ON (A.a=B.b) 

A LEFT JOIN B USING(a)

左外连接的结果如下图红色部分

 

示例:查询所有学生的选课信息,包括没选课的学生

test=# select * from tbl_student left join tbl_student_course using(stu_id) left join tbl_course using(course_id); course_id | stu_id | stu_name | course_name -----------+--------+----------+------------- 2 |1 | 张三 | 大学英语 4 |1 | 张三 | 电影欣赏 4 |2 | 李四 | 电影欣赏 4 |3 | 王五 | 电影欣赏NULL |4 | 麻子 | NULL(5 rows)

 

四.右外连接(RIGHT JOIN / RIGHT OUTER JOIN)

右外连接其实是一个内连接然后加上右表独有的数据行,结果集中左表的字段自动补充NULL。

RIGHT OUTER JOIN ,其中OUTER可以省略。

语法:

A RIGHT JOIN B ON (A.a=B.b) 

A RIGHT JOIN B USING(a)

右外连接的结果如下图红色部分

 

示例:查询所有课程被选情况

test=# select * from tbl_student right join tbl_student_course using(stu_id) right join tbl_course using(course_id); course_id | stu_id | stu_name | course_name -----------+--------+----------+------------- 2 |1 | 张三 | 大学英语 4 |1 | 张三 | 电影欣赏 4 |2 | 李四 | 电影欣赏 4 |3 | 王五 | 电影欣赏 3 | NULL | NULL | 大学物理 1 | NULL | NULL | 高等数学(6 rows)

 

五.全外连接(FULL JOIN / FULL OUTER JOIN)

全外连接其实是一个内连接然后加上左表和右表独有的数据行,左表独有的数据行右表的字段补充NULL,右表独有的数据行左表字段补充NULL。

FULL OUTER JOIN,其中OUTER可以省略。

语法:

A FULL OUTER JOIN B ON (A.a = B.b)

A FULL OUTER JOIN B USING(a)

全外连接的结果如下图红色部分

 

示例:查询所有学生和课程的选课信息

test=# select * from tbl_student full join tbl_student_course using(stu_id) full join tbl_course using(course_id); course_id | stu_id | stu_name | course_name -----------+--------+----------+------------- 2 |1 | 张三 | 大学英语 4 |1 | 张三 | 电影欣赏 4 |2 | 李四 | 电影欣赏 4 |3 | 王五 | 电影欣赏NULL |4 | 麻子 | NULL 3 | NULL | NULL | 大学物理 1 | NULL | NULL | 高等数学(7 rows)

 

查询只在左表存在的数据

 

示例:查询没有选课的学生

test=# select * from tbl_student left join tbl_student_course using(stu_id) where tbl_student_course.stu_id is null; stu_id | stu_name | course_id --------+----------+-----------4 | 麻子 |NULL(1 row)

 

NOT IN存在很大的性能瓶颈,除NOT EXISTS外,也可以使用这种查询方式作为替代方案。

查询只在右表中存在的数据

 

示例:查询没有被选的课程

test=# select * from tbl_student_course right join tbl_course using(course_id) where tbl_student_course.course_id is null; course_id | stu_id | course_name -----------+--------+------------- 1 | NULL | 高等数学 3 | NULL | 大学物理(2 rows)

 

 

查询只在左表或只在右表存在的数据

 

示例:查询没有选课的学生和没有被选的课程

test=# select * from tbl_student full join tbl_student_course using(stu_id) full join tbl_course using(course_id) where tbl_student.stu_id is null or tbl_course.course_id is null; course_id | stu_id | stu_name | course_name -----------+--------+----------+-------------NULL |4 | 麻子 | NULL 3 | NULL | NULL | 大学物理 1 | NULL | NULL | 高等数学(3 rows)

 

所有的JOIN查询,只要理解了下面的图,一切就OK了!

 

 

原文链接:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。