MySQL连接查询

 进阶6:多表连接查询
 
        笛卡尔乘积:如果连接条件省略或无效则会出现
        解决办法:添加上连接条件
        
一、传统模式下的连接 :等值连接——非等值连接
 
 
        1.等值连接的结果 = 多个表的交集
        2.n表连接,至少需要n-1个连接条件
        3.多个表不分主次,没有顺序要求
        4.一般为表起别名,提高阅读性和性能
        
二、sql99语法:通过join关键字实现连接
 
        内连接:等值连接,非等值连接,自连接
        外连接:左外连接,右外连接,全外连接
        交叉连接       
含义:1999年推出的sql语法
        支持:
        等值连接、非等值连接 (内连接)
        外连接
        交叉连接
        
        语法:
        
        select 字段,...
        from 1
        inner|left outer|right outer|crossjoin 2 on  连接条件
        inner|left outer|right outer|crossjoin 3 on  连接条件
        where 筛选条件】
        group by 分组字段】
        having 分组后的筛选条件】
        order by 排序的字段或表达式】
        
        好处:语句上,连接条件和筛选条件实现了分离,简洁明了!
 
        

 

#等值连接:

mysql> select name,boyName from boys,beauty where boys.id= beauty.boyfriend_id;

查询员工名和对应的部门名

mysql> select last_name,department_name from employees,departments where employees.department_id=departments.department_id;

 

查询员工名、工种号、工种名

mysql> select last_name,department_name from employees,departments where employees.department_id=departments.department_id;

为表其别名

mysql> select last_name,e.job_id,job_title from employees e,jobs j where e.job_id =j.job_id;

起别名前面再用完整表名就不好用了

 

加筛选

查询城市名中第二个字母为o的部门名和城市名

 
三、自连接
 
案例:查询员工名和直接上级的名称
都在这个表中,建立某两个记录的关系,一张表找了两遍
mysql> select e.last_name,m.last_name,e.manager_id from employees e, employees m where e.manager_id=m.employee_id;
+-------------+-----------+------------+
| last_name   | last_name | manager_id |
+-------------+-----------+------------+
| Kochhar     | K_ing     |        100 |
| De Haan     | K_ing     |        100 |
| Hunold      | De Haan   |        102 |
sql99
 
        SELECT e.last_name,m.last_name
        FROM employees e
        JOIN employees m ON e.`manager_id`=m.`employee_id`;
 
sql92
 
        
        SELECT e.last_name,m.last_name
        FROM employees e,employees m 
        WHERE e.`manager_id`=m.`employee_id`;

 

**********92语法容易混淆,没有join

 


 

mysql> select department_name,city from departments d,locations l where d.location_id =l.location_id and city like'_o%';

+-----------------+---------------------+

| department_name | city                |

+-----------------+---------------------+

| IT              | Southlake           |

| Shi             | South San Francisco |

| Mar             | Toronto             |

| Hum             | London              |

+-----------------+---------------------+

 

加分组

查询每个城市的部门个数

mysql> select count(*) num,city from departments d,locations l where d.location_id=l.location_id group by city;

+-----+---------------------+

| num | city                |

+-----+---------------------+

|   1 | London              |

|   1 | Munich              |

|   1 | Oxford              |

|  21 | Seattle             |

 

查询有奖金的每个部门名和部门的领导编号和该部门的最低工资

mysql> select department_name,d.manager_id,min(salary) from departments d,employees e where d.department_id=e.department_id and commission_pct is not null group by department_namee,d.manager_id;

+-----------------+------------+-------------+

| department_name | manager_id | min(salary) |

+-----------------+------------+-------------+

| Sal             |        145 |     6100.00 |

+-----------------+------------+-------------+

加排序

查询每个工种的工种名和员工的个数,并按照员工个数降序

mysql> select job_title,count(*) from jobs j,employees e where e.job_id=j.job_id group by job_title order by count(*) desc;

+---------------------------------+----------+

| job_title                       | count(*) |

+---------------------------------+----------+

| Sales Representative            |       30 |

| Shipping Clerk                  |       20 |

 

#非等值连接:

大于小于等等

查询员工的工资和工资级别

mysql> select employee_id,salary,grade_level from employees e,job_grades j where salary between j.lowest_sal and j.highest_sal;

+-------------+----------+-------------+

| employee_id | salary   | grade_level |

+-------------+----------+-------------+

|         100 | 24000.00 | E           |

|         101 | 17000.00 | E           |

|         102 | 17000.00 | E           |

 

 

mysql> select department_name,city from departments d inner join locations l on d.location_id =l.location_id where city like'_o%';

 

*****inner 可以省略

Inner join 对应了92语法中的等值连接

 

查询哪个部门没员工

mysql> select d.*,employee_id from departments d left outer join employees e on d.department_id=e.department_id where e.employee_id is null;

 

#外连接

 

用于查询一个表中有一个表中没有

 

查询不在男神表男朋友的女生

 

如果从表中有和它匹配的则显示匹配的值

 

如果没有则显示null

 

主表从表

 

左外连接,left join左边的是主表

 

右外连接,right join右边的是主表

 

左外和右外交换两个表的顺序实现同样的效果

 

mysql> select b.name,bo.* from beauty b left outer join boys bo on b.boyfriend_id=bo.id where bo.id is null;  最好选主键

 

全外连接,不能执行

mysql> select b.*,bo.* from breauty b full outer join boys bo on b.boyfriend_id=bo.id;

交叉连接,其实就是笛卡尔乘积

mysql> select b.*,bo.* from beauty b cross join boys bo;

mysql> select last_name,e.job_id,job_title from employees e inner join jobs j on e.job_id =j.job_id;

 

 

 
posted @ 2018-04-08 15:33  王毅2016  阅读(295)  评论(0编辑  收藏  举报