连接查询——sql92

进阶6:连接查询

含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1 有m行,表2有n行,结果=m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件

分类

按年代分类:

  • sql92标准:仅仅支持内连接(等值、非等值、自连接)
  • sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接

按功能分类:

  1. 内连接:等值连接、非等值连接、自连接
  2. 外连接:左外连接、右外连接、全外连接
  3. 交叉连接

sql92标准

1、等值连接

特点:
①多表等值连接的结果为多表的交集部分
②n表连接,至少需要n-1个连接条件
③多表的顺序没有要求
④一般需要为表起别名
⑤可以搭配前面介绍的所有子句使用,比如排序、分组、筛选

案例1 :查询女神名和对应的男神名

SELECT 
  NAME,
  boyName 
FROM
  boys,
  beauty 
WHERE beauty.`boyfriend_id` = boys.`id` ;

结果:
在这里插入图片描述
案例2:查询员工名和对应的部门名

SELECT 
  last_name,
  department_name 
FROM
  employees,
  departments 
WHERE employees.`department_id` = departments.`department_id` ;

结果:
在这里插入图片描述

(1)为表起别名

  • 提高语句的简洁度
  • 区分多个重名的字段
    注意:如果为表起了别名,则查询的字段就不能使用原来的表名去限定

案例:查询员工名、工种号、工种名

SELECT 
  last_name,
  e.job_id,
  job_title 
FROM
  employees AS e,
  jobs AS j 
WHERE e.`job_id` = j.`job_id` ;

结果:

(2)两个表的顺序是可以调换
案例:查询员工名、工种号、工种名

SELECT 
  e.last_name,
  e.job_id,
  j.job_title 
FROM
  jobs j,
  employees e 
WHERE e.`job_id` = j.`job_id` ;

(3)可以加筛选
案例1:查询有奖金的员工名、部门名

SELECT 
  e.last_name,
  d.department_name,
  commission_pct 
FROM
  employees e,
  departments d 
WHERE d.`department_id` = e.`department_id` 
  AND e.`commission_pct` IS NOT NULL ;

结果:
在这里插入图片描述
案例2:查询城市名中第二个字符为o的部门名和城市名

SELECT 
  department_name,
  city 
FROM
  departments d,
  locations l 
WHERE d.`location_id` = l.`location_id` 
  AND l.`city` LIKE "_o%" ;

结果:
在这里插入图片描述
(4)可以加分组

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

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

结果:
在这里插入图片描述
案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资

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

结果:
在这里插入图片描述
(5)可以加排序
案例:查询每个工种的工种名和员工的个数,并且按员工个数降序

SELECT 
  job_title,
  COUNT(*) 员工个数 
FROM
  employees e,
  jobs j 
WHERE e.`job_id` = j.`job_id` 
GROUP BY j.`job_title` 
ORDER BY COUNT(*) DESC ;

结果:
在这里插入图片描述
(6)可以实现三表连接
案例:查询员工名、部门名和所在的城市

SELECT 
  last_name,
  department_name,
  city 
FROM
  departments d,
  employees e,
  locations l 
WHERE d.`department_id` = e.`department_id` 
  AND d.`location_id` = l.`location_id` 
  AND city LIKE 'S%' 
ORDER BY department_name DESC ;

结果:在这里插入图片描述

2、非等值连接

语法:
SELECT 查询列表
FROM 表1 AS 别名,表2 AS 别名
WHERE 非等值的连接条件

案例:查询员工的工资和工资级别

SELECT 
  salary,
  grade_level 
FROM
  employees e,
  job_grades g 
WHERE salary BETWEEN g.`lowest_sal` 
  AND g.`highest_sal` ;

结果:
在这里插入图片描述

3自连接

语法:

SELECT 查询列表
FROM 表1 AS 别名1,表1 AS 别名2
WHERE 条件

案例:查询 员工名和上级的名称

SELECT 
  e.employee_id,
  e.last_name,
  m.employee_id,
  m.last_name 
FROM
  employees e,
  employees m 
WHERE e.`manager_id` = m.`employee_id` ;

结果:
在这里插入图片描述

测试

1、显示员工表的最大工资,工资平均值

SELECT 
  MAX(salary) 最大工资,
  AVG(salary) 平均工资 
FROM
  employees ;

结果:
在这里插入图片描述
2、查询员工表的employee_id,job_id,last_name,按department_id降序,salary升序

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

结果:
在这里插入图片描述
3、查询员工表的job_id中包含a和e的,并且a在e的前面

SELECT 
  job_id 
FROM
  employees 
WHERE job_id LIKE "%a%e%" ;

结果:
在这里插入图片描述
4、已知表student,里面有id(学号),NAME,gradeId(年级编号)
已知表grade,里面有id(年级编号),NAME(年级名)
已知表result,里面有id,score,studentNo(学号)
要求查询姓名、年级名、成绩

SELECT 
  s.name,
  g.name,
  r.score 
FROM
  student s,
  grade g,
  result r 
WHERE s.id = r.studentNO 
  AND s.gradeID = g.id ;

5、显示当前日期,以及去前后空格,截取子字符串的函数

SELECT NOW()
SELECT TRIM("  aa  ")
SELECT SUBSTR("aaaa",2,4)

猜你喜欢

转载自blog.csdn.net/Txixi/article/details/114016483
今日推荐