【MySQL】内外连接

内连接

内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选
语法:

select 字段 from1 inner join2 on 连接条件 and 其他条件;
--where
mysql> select ename,dname from emp,dept where emp.deptno=dept.deptno and ename='SMITH';
+-------+----------+
| ename | dname    |
+-------+----------+
| SMITH | RESEARCH |
+-------+----------+
--内连接
mysql> select ename,dname from emp inner join dept on  emp.deptno=dept.deptno and ename='SMITH';
+-------+----------+
| ename | dname    |
+-------+----------+
| SMITH | RESEARCH |
+-------+----------+

外连接

左外连接

如果联合查询,左侧的表完全显示我们就说是左外连接

mysql> select * from stu;
+------+------+
| id   | name |
+------+------+
|    1 | jack |
|    2 | tom  |
|    3 | kity |
|    4 | nono |
+------+------+

mysql> select * from exam;
+------+-------+
| id   | grade |
+------+-------+
|    1 |    56 |
|    2 |    76 |
|   11 |     8 |
+------+-------+

--内连接:拼接符合条件的表
mysql> select * from stu inner join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
+------+------+------+-------+

--左外连接:在完整显示左侧的表基础上,显示符合条件的
mysql> select * from stu left join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
|    3 | kity | NULL |  NULL |
|    4 | nono | NULL |  NULL |
+------+------+------+-------+

右外连接

如果联合查询,右侧的表完全显示我们就说是右外连接。
左外连接和右外连接可以转化,注意连接位置就行

--右外
mysql> select * from stu right join exam on stu.id=exam.id;
+------+------+------+-------+
| id   | name | id   | grade |
+------+------+------+-------+
|    1 | jack |    1 |    56 |
|    2 | tom  |    2 |    76 |
| NULL | NULL |   11 |     8 |
+------+------+------+-------+

--左外
mysql> select * from exam left join stu on stu.id=exam.id;
+------+-------+------+------+
| id   | grade | id   | name |
+------+-------+------+------+
|    1 |    56 |    1 | jack |
|    2 |    76 |    2 | tom  |
|   11 |     8 | NULL | NULL |

mysql> select d.dname,e.* from dept d left join emp e  on d.deptno=e.deptno order by d.deptno asc;
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
| dname      | empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno |
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+
| ACCOUNTING | 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
| ACCOUNTING | 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
| ACCOUNTING | 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
| RESEARCH   | 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
| RESEARCH   | 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
| RESEARCH   | 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
| RESEARCH   | 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
| RESEARCH   | 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
| SALES      | 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
| SALES      | 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
| SALES      | 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
| SALES      | 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
| SALES      | 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
| SALES      | 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
| OPERATIONS |   NULL | NULL   | NULL      | NULL | NULL                |    NULL |    NULL |   NULL |
+------------+--------+--------+-----------+------+---------------------+---------+---------+--------+

小练习

获取所有员工当前的manager

--where
select dp.emp_no ,dm.emp_no from
dept_emp dp , dept_manager dm 
where dp.dept_no=dm.dept_no
and dp.emp_no!=dm.emp_no;
--内连接
select dp.emp_no ,dm.emp_no from
dept_emp dp inner join dept_manager dm on dp.dept_no=dm.dept_no
where dp.emp_no!=dm.emp_no;

分数排名
第一步:查找排名,即去重后比该分数多的行数
第二步:对分数进行降序

select score,
(
--找出排名
    select count(distinct score) from Scores where score>=s.score
) as 'rank'
from Scores s
order by score desc;

使用rank(函数)rank()函数及其用法

select score, dense_rank() over (order by score desc) as 'rank'  #这个rank之所以要加引号,因为rank本身是个函数,直接写rank会报错
from scores;

换座位 Exchange Seats
小美是一所中学的信息科技老师,她有一张 seat 座位表,平时用来储存学生名字和与他们相对应的座位 id。

其中纵列的 id 是连续递增的

小美想改变相邻俩学生的座位。

你能不能帮她写一个 SQL query 来输出小美想要的结果呢?

+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Abbot   |
|    2    | Doris   |
|    3    | Emerson |
|    4    | Green   |
|    5    | Jeames  |
+---------+---------+

假如数据输入的是上表,则输出结果如下:

+---------+---------+
|    id   | student |
+---------+---------+
|    1    | Doris   |
|    2    | Abbot   |
|    3    | Green   |
|    4    | Emerson |
|    5    | Jeames  |
+---------+---------+

注意:如果学生人数是奇数,则不需要改变最后一个同学的座位。

select 
    IF(mod(id,2)=0,id-1,IF(id=(select max(id) from seat),id,id+1)) as id,student
from seat
order by id

IF函数:该函数的执行机制是判断第一个参数是否为真,若为真则返回第二个参数,若为假则返回地三个参数
IF(true,0,1),返回0
IF(false,0,1),返回1
本题类似C/C++遍历数组,循环判断id大小,然后改变id

猜你喜欢

转载自blog.csdn.net/m0_54469145/article/details/131890965