MYSQL初阶学习笔记——进阶6:连接查询

#进阶6:连接查询
/*
含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

笛卡尔乘积现象:表1:m行,表2:n行,结果m*n行

发生原因;没有有效的连接条件
如何避免:添加有效的连接条件

分类:
    按年代分类;
    sql92标准:仅仅支持内连接
    sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接
    
    按功能分类:
        内连接:等值连接,非等值连接,自连接
        外连接:左外连接,右外连接,全外连接
        交叉连接

*/

#一、sql标准

##1.等值连接

/*
特点总结:
1.多表等值连接的结果为多表的交集部门
2.n表连接,至少需要n-1连接条件
3.多表的顺序没有要求
4.一般需要为表起别名
5.可以搭配之前所有子句使用,包括排序,分组,筛选



*/

#案例1:员工名和对应的部门名
SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id=departments.department_id;

#案例2:查询员工名、工种号、工种名
SELECT last_name,employees.job_id,job_title
FROM employees,jobs
WHERE jobs.job_id=employees.job_id;

#2.为表起别名

##若为表起了别名。则查询字段不能使用原表名了。应使用别名

#案例:查询员工名、工种号、工种名(别名类型)
SELECT last_name,e.job_id,job_title
FROM employees e,jobs
WHERE jobs.job_id=e.job_id;


#3.调换表顺序不影响结果

#案例:查询员工名、工种号、工种名(别名类型)
SELECT last_name,e.job_id,job_title
FROM jobs j,employees e
WHERE j.job_id=e.job_id;


#4.可以加筛选条件(Where 后用 and 加条件)

#案例1:查询有奖金的员工名、部门名
SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id=departments.department_id
AND employees.`commission_pct` IS NOT NULL;

#案例2:查询城市名中第二个字符为o 的部门名和城市名
SELECT department_name,city
FROM departments AS d,locations AS l
WHERE d.`location_id`=l.`location_id`
AND city LIKE '_o%';

#5.可以加分组?

#案例1:查询每个城市的部门个数

SELECT COUNT(*),city
FROM departments AS d,locations AS l
WHERE d.`location_id`=l.`location_id`
GROUP BY city;

#案例2:查询有奖金的每个部门的部门名和部门领导编号 以及该部门的最低工资

SELECT department_name,d.manager_id,MIN(salary)
FROM departments d,employees e
WHERE d.`manager_id`=e.`manager_id`
AND e.`commission_pct` IS NOT NULL
GROUP BY department_name;

#6.可以加排序?

#案例1:查询每个工种的工种名和员工个数,并按员工个数降序
SELECT j.`job_id`,job_title,COUNT(*)
FROM employees e,jobs j
WHERE e.job_id=j.job_id
GROUP BY job_title
ORDER BY COUNT(*) DESC;

#7.实现三表连接?

#案例:查询员工名、部门名和所在城市
SELECT last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.`department_id`=d.`department_id`
AND d.`location_id`=l.`location_id`;

#案例:查询员工名、部门名和所在城市(城市名以s开头,按城市名长度降序排列)
SELECT last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.`department_id`=d.`department_id`
AND d.`location_id`=l.`location_id`
AND city LIKE 's%'
ORDER BY LENGTH(city) DESC;

##2.非等值连接

#先创建工资等级表job_grades
/*
CREATE TABLE job_grades
(grade_level VARCHAR(3),
 lowest_sal  int,
 highest_sal int);

INSERT INTO job_grades
VALUES ('A', 1000, 2999);

INSERT INTO job_grades
VALUES ('B', 3000, 5999);

INSERT INTO job_grades
VALUES('C', 6000, 9999);

INSERT INTO job_grades
VALUES('D', 10000, 14999);

INSERT INTO job_grades
VALUES('E', 15000, 24999);

INSERT INTO job_grades
VALUES('F', 25000, 40000);
*/

#案例1:查询员工的工资和工资级别
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary  BETWEEN g.`lowest_sal` AND g.`highest_sal`;
    #意思是,将salary处于一个范围内,其grade_leve就会连接g表的级别


##3.自连接(自己连接自己,必须带有一些字段能匹配)
    #只是将一个表用两次进行查询连接 

#案例1:查询 员工名和上级的名称 (manager_id 与 employee_id 代表一个人)

SELECT e.employee_id,e.last_name,e.manager_id,m.employee_id,m.last_name
FROM employees e,employees m  #用别名可完美避免歧义
WHERE e.manager_id=m.employee_id;




#========================Test=============================
#1.显示员工表的最大工资,工资平均值(每个job_id下)
SELECT MAX(salary),AVG(salary),job_id
FROM employees
GROUP BY job_id
ORDER BY AVG(salary);

#2.查询员工表的employee_id,job_id,last_name,按department_id降序,salary升序

SELECT employee_id,job_id,last_name,salary,department_id
FROM employees
ORDER BY department_id DESC,salary;


#3.查询员工表job_id包含 a 和 e的,且a%e
SELECT job_id,last_name
FROM employees
WHERE job_id LIKE '%a%e%';


#4.
/*
已知表student,里面有id(学号),name,gradeId(年级编号)
已知表grade,里面有id(年级编号),name(年级名)
已知表result,里面有id,score,studentNu(学号)
查询 姓名 年级 成绩
*/
SELECT s.name,g.name,r.score
FROM student s,grade g,result r
WHERE s.gradeId=s.id
AND s.id=r.studentNu;

#5.显示当前日期,以及去前后空格,截取子字符串的函数
SELECT NOW();
SELECT TRIM('   111    ') AS exa,LENGTH(TRIM('   111    '));
SELECT SUBSTR('love',3);
SELECT SUBSTR('love',2,2);
全部评论

相关推荐

03-29 12:10
门头沟学院 C++
点赞 评论 收藏
分享
02-22 20:28
重庆大学 Java
程序员牛肉:首先不要焦虑,你肯定是有希望的。 首先我觉得你得好好想一想自己想要什么。找不到开发岗就一定是失败的吗?那开发岗的35岁危机怎么说?因此无论是找工作还是考公我觉得你都需要慎重的想一想。但你一定要避开这样一个误区:“我是因为找不到工作所以不得不选择考公”。 千万不要这么想。你这个学历挺好的了,因此你投后端岗肯定是有面试机会的。有多少人简历写的再牛逼,直接连机筛简历都过不去有啥用?因此你先保持自信一点。 以你现在的水平的话,其实如果想要找到暑期实习就两个月:一个月做项目+深挖,并且不断的背八股。只要自己辛苦一点,五月份之前肯定是可以找到暑期实习的,你有点太过于高看大家之间的技术差距了。不要焦虑不要焦虑。 除此之外说回你这个简历内容的话,基本可以全丢了。如果想做后端,先踏踏实实做两个项目再说+背八股再说。如果想考公,那就直接备战考公。 但是但是就像我前面说的:你考公的理由可以是因为想追求稳定,想追求轻松。但唯独不能是因为觉得自己找不到工作。不能这么小瞧自己和自己的学历。
点赞 评论 收藏
分享
昨天 12:26
已编辑
中南大学 PHP
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务