七:連接查詢(內連接、外連接)


#進階6:連接查詢
說明:又稱多表查詢,當查詢語句涉及到的字段來自於多個表時,就會用到連接查詢
笛卡爾乘積現象:表1 有m行,表2有n行,結果=m*n行
      發生原因:沒有有效的連接條件
     如何避免:添加有效的連接條件
分類:
    按年代分類:
    1、sql92標准:僅僅支持內連接
            內連接:
                 等值連接
                 非等值連接
                 自連接
   2、sql99標准【推薦】:支持內連接+外連接(左外和右外)+交叉連接
    按功能分類:
        內連接:
              等值連接
             非等值連接
             自連接
        外連接:
             左外連接
             右外連接
             全外連接  
      交叉連接
#引入案例
#查詢女神名和對應的男神名
SELECT * FROM beauty;
SELECT * FROM boys;
SELECT NAME,boyName FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;
#---------------------------------sql92標准------------------
#一、內連接
/*
語法:
select 查詢列表
from 表1 別名,表2 別名
where 連接條件
and 篩選條件
group by 分組列表
having 分組后篩選
order by 排序列表
執行順序:
1、from子句
2、where子句
3、and子句
4、group by子句
5、having子句
6、select子句
7、order by子句
#一)等值連接
① 多表等值連接的結果為多表的交集部分
②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`;
#2、為表起別名
①提高語句的簡潔度
②區分多個重名的字段
注意:如果為表起了別名,則查詢的字段就不能使用原來的表名去限定
#查詢員工名、工種號、工種名
SELECT e.last_name,e.job_id,j.job_title
FROM employees  e,jobs j
WHERE e.`job_id`=j.`job_id`;
#3、兩個表的順序是否可以調換
#查詢員工名、工種號、工種名
SELECT e.last_name,e.job_id,j.job_title
FROM jobs j,employees e
WHERE e.`job_id`=j.`job_id`;
#4、可以加篩選
#案例:查詢有獎金的員工名、部門名
SELECT last_name,department_name,commission_pct
FROM employees e,departments d
WHERE e.`department_id`=d.`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 city LIKE '_o%';
#5、可以加分組
#案例1:查詢每個城市的部門個數
SELECT COUNT(*) 個數,city
FROM departments d,locations 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.`department_id`=e.`department_id`
AND commission_pct IS NOT NULL
GROUP BY department_name,d.`manager_id`;
#6、可以加排序
#案例:查詢每個工種的工種名和員工的個數,並且按員工個數降序
SELECT 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`
AND city LIKE 's%'
ORDER BY department_name DESC;
#二)非等值連接
#案例1:查詢員工的工資和工資級別
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';
 
select salary,employee_id from employees;
select * from 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);
#三)自連接
#案例:查詢 員工名和上級的名稱
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`;
#------------------------SQL99語法
#一、內連接
語法:
SELECT 查詢列表                                                              select  查詢列表
FROM 表名1 別名                                                              from  表1 別名
【INNER】 JOIN  表名2 別名                                           【inner】jion  表2 別名 on 連接條件
ON 連接條件                                                                     【inner】join  表3 別名 on 連接條件
WHERE 篩選條件                                                               where 分組前的篩選條件
GROUP BY 分組列表                                                         GROUP BY 分組列表
HAVING 分組后篩選                                                           HAVING 分組后篩選
ORDER BY 排序列表;                                                        ORDER BY 排序列表;
SQL92和SQL99的區別:
    SQL99,使用JOIN關鍵字代替了之前的逗號,並且將連接條件和篩選條件進行了分離,提高閱讀性!!!
#一)等值連接
#①簡單連接
#案例:查詢員工名和部門名
SELECT last_name,department_name
FROM departments d 
 JOIN  employees e 
ON e.department_id =d.department_id;
#②添加篩選條件
#案例1:查詢部門編號>100的部門名和所在的城市名
SELECT department_name,city
FROM departments d
JOIN locations l
ON d.`location_id` = l.`location_id`
WHERE d.`department_id`>100;
#③添加分組+篩選
#案例1:查詢每個城市的部門個數
SELECT COUNT(*) 部門個數,l.`city`
FROM departments d
JOIN locations l
ON d.`location_id`=l.`location_id`
GROUP BY l.`city`;
#④添加分組+篩選+排序
#案例1:查詢部門中員工個數>10的部門名,並按員工個數降序
SELECT COUNT(*) 員工個數,d.department_name
FROM employees e
JOIN departments d
ON e.`department_id`=d.`department_id`
GROUP BY d.`department_id`
HAVING 員工個數>10
ORDER BY 員工個數 DESC;
#二)非等值連接
#案例:查詢部門編號在10-90之間的員工的工資級別,並按級別進行分組
SELECT * FROM sal_grade;
SELECT COUNT(*) 個數,grade
FROM employees e
JOIN sal_grade g
ON e.`salary` BETWEEN g.`min_salary` AND g.`max_salary`
WHERE e.`department_id` BETWEEN 10 AND 90
GROUP BY g.grade;
#三)自連接
#案例:查詢員工名和對應的領導名
SELECT e.`last_name`,m.`last_name`
FROM employees e
JOIN employees m
ON e.`manager_id`=m.`employee_id`;
#二、外連接      
說明:查詢結果為主表中所有的記錄,如果從表有匹配項,則顯示匹配項;如果從表沒有匹配項,則顯示null
應用場景:一般用於查詢主表中有但從表沒有的記錄
特點:
1、外連接分主從表,兩表的順序不能任意調換
2、左連接的話,left join左邊為主表
   右連接的話,right join右邊為主表
語法:
select 查詢列表
from 表1 別名
left / right / full 【outer】 join 表2 別名                             注意 :full 為全連
on 連接條件
where 篩選條件;
 
USE girls;
#案例1:查詢所有女神記錄,以及對應的男神名,如果沒有對應的男神,則顯示為null
#左連接
SELECT b.*,bo.*
FROM beauty b
LEFT JOIN boys bo ON b.`boyfriend_id` = bo.`id`;
#右連接
SELECT b.*,bo.*
FROM boys bo
RIGHT JOIN  beauty b ON b.`boyfriend_id` = bo.`id`;
#案例2:查哪個女神沒有男朋友
#左連接
SELECT b.`name`
FROM beauty b
LEFT JOIN boys bo ON b.`boyfriend_id` = bo.`id`
WHERE bo.`id`  IS NULL;
#右連接
SELECT b.*,bo.*
FROM boys bo
RIGHT JOIN  beauty b ON b.`boyfriend_id` = bo.`id`
WHERE bo.`id`  IS NULL;
#案例3:查詢哪個部門沒有員工,並顯示其部門編號和部門名
SELECT COUNT(*) 部門個數
FROM departments d


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM