#sql99语法
/*
 语法:
      select 查询列表
      from 表1 别名1 【连接类型】
      join 表2 别名2
      on 连接条件
      【where 筛选条件】
      【group by 分组列表】
      【having 筛选条件】
      【order by 排序列表】
      
  分类
     内连接(*):【inner】:求两表中的相匹配的记录(交集)
     外连接
           左外(*):left 【outer】
           右外(*):right【outer】
           全外:full【outer】
     交叉连接:cross
 */
 USE myemployees;
#一>、内连接
(两表相匹配的记录)和sql92结果相同;==求交值
#1、等值连接
 #案例1:查询员工名、部门名
 SELECT last_name,department_name FROM employees e INNER JOIN departments d ON e.`department_id`=d.`department_id`;
#加筛选
 #案例2:查询名字中包含e的员工名、工种名
 SELECT last_name,job_title FROM employees e INNER JOIN jobs j ON e.`job_id` = j.`job_id` WHERE e.`last_name` LIKE '%e%';
#添加分组和查询
 #案例3:查询部门个数>3的城市名和部门个数
 SELECT 
   city,
   COUNT(*) 部门个数 
 FROM
   departments d 
   INNER JOIN locations l 
     ON d.`location_id` = l.`location_id` 
 GROUP BY city 
 HAVING 部门个数 > 3 ;
#添加排序
 #案例4:查询哪个部门的部门员工个数>3的部门名和员工个数,并按个数降序
 SELECT 
   department_name,
   COUNT(employee_id) 员工个数 
 FROM
   employees e 
   INNER JOIN departments d 
     ON e.`department_id` = d.`department_id` 
 GROUP BY department_name 
 HAVING 员工个数 > 3 
 ORDER BY 员工个数 DESC;
#案例5:查询员工名、部门名、工种名,并按部门名降序
 SELECT 
   last_name,
   department_name,
   job_title 
 FROM
   employees e 
   INNER JOIN departments d 
     ON e.`department_id` = d.`department_id` 
   INNER JOIN jobs j 
     ON e.`job_id` = j.`job_id` 
 ORDER BY d.`department_name` DESC ;
#2、非等值连接
 #案例1:查询员工的工资级别
 SELECT 
   last_name,
   salary,
   grade_level 
 FROM
   employees e 
   JOIN job_grades j 
     ON e.`salary` BETWEEN j.`lowest_sal` 
     AND j.`highest_sal` ORDER BY j.`grade_level`;
  
 #案例2:查询每个工资级别的员工个数,按照个数降序排序
 SELECT 
   COUNT(*) 员工个数,
   grade_level 
 FROM
   employees e 
   JOIN job_grades j 
     ON e.`salary` BETWEEN j.`lowest_sal` 
     AND j.`highest_sal` 
 GROUP BY grade_level 
 HAVING 员工个数>20
 ORDER BY 员工个数 DESC ;
 #案例:查询员工名和上级名
 SELECT e.last_name 员工名,m.last_name 上级名 FROM employees e INNER JOIN employees m ON e.`manager_id` = m.`employee_id`;
#二>、外连接
 /*
应用场景:主表有的记录,附表没有与之匹配的
特点:
      左(右)外连接的查询结果为主表中的所有记录:
         如果在从表中有与它相匹配的,则显示匹配的值
         如果在从表中没有与它相匹配的,则显示为Null
         外连接结果= 内连接结果(匹配)+主表中有二从表中没有的记录
         
       判断主表:左外左边的,右外右边的
       
      
      全外连接=内连接+表1中有但表2中没有的记录+表2中有但表1中没有的记录
 */
#左(右)外连接
#案例1:查询没有男朋友的女神名
 USE girls;
#比较下面显示结果体会外连接
 SELECT g.*,b.* FROM boys b LEFT JOIN beauty g ON g.`boyfriend_id`=b.`id`;
 SELECT g.*,b.* FROM beauty g LEFT JOIN boys b ON g.`boyfriend_id`=b.`id`;
 SELECT g.*,b.* FROM beauty g LEFT JOIN boys b ON g.`boyfriend_id`=b.`id` WHERE b.id IS NULL;
#案例1:查询哪个部门没有员工(部门表有记录,但员工表没有相匹配的
 USE myemployees;
 SELECT 
   d.`department_id`,
   d.`department_name` 
 FROM
   departments d 
   LEFT JOIN employees e 
     ON d.`department_id` = e.`department_id` 
 WHERE e.`employee_id` IS NULL ;
#全外
 USE girls;
 SELECT g.*,b.* FROM beauty g FULL OUTER JOIN boys b ON g.`boyfriend_id` = b.id;
#交叉连接
 SELECT g.*,b.* FROM beauty g CROSS JOIN boys b ;
#sql92和sql99
#练习1:查询编号>3的女神的男朋友信息,如果有则详细列出,没有用Null填充
 SELECT g.id,b.* FROM beauty g LEFT JOIN boys b ON g.`boyfriend_id`=b.`id` WHERE g.`id`>3;
#练习2:查询哪个城市没有部门
 USE myemployees;
 SELECT l.city FROM locations l LEFT JOIN departments d ON l.`location_id`=d.`location_id` WHERE d.`department_id` IS NULL;
#练习3:查询部门名为sal或IT的员工信息
 SELECT 
   e.*,
   d.`department_name` 
 FROM
   employees e 
   INNER JOIN departments d 
     ON e.`department_id` = d.`department_id` 
 WHERE d.`department_name` IN ('SAL', 'IT') ;










