多表查詢
多表查詢語法
1 select 2 字段列表 3 from 4 表名列表 5 where 6 條件
使用多表查詢出現的問題

1 CREATE TABLE department( 2 id INT PRIMARY KEY AUTO_INCREMENT, 3 dep_name VARCHAR(5), 4 dep_location VARCHAR(4) 5 ); 6 7 CREATE TABLE employe( 8 id INT PRIMARY KEY AUTO_INCREMENT, 9 NAME VARCHAR(4), 10 age INT, 11 dep_id INT,# 外鍵列 12 13 CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id) 14 15 ); 16 17 18 19 INSERT INTO department (dep_name,dep_location)VALUES ('研發部','廣州'); 20 INSERT INTO department (dep_name,dep_location)VALUES ('銷售部','深圳'); 21 22 23 INSERT INTO employe (NAME,age,dep_id)VALUES ('張三',20,1); 24 INSERT INTO employe (NAME,age,dep_id)VALUES ('李四',20,1); 25 INSERT INTO employe (NAME,age,dep_id)VALUES ('王五',20,1); 26 INSERT INTO employe (NAME,age,dep_id)VALUES ('趙六',20,2); 27 INSERT INTO employe (NAME,age,dep_id)VALUES ('孫七',20,2); 28 INSERT INTO employe (NAME,age,dep_id)VALUES ('老八',20,2);
select * from 表名1,表名2;該語句的查詢結果,有笛卡爾積(集合A,B,去兩個表所有組合情況)表示:結果一共 X 行 (X=表1行數*表2行數)
那么就需要消除無用的數據
解決方法:
1,內連接查詢
2,外連接查詢
【交叉連接、自連接】
3,子查詢
4,聯合查詢
內連接查詢
隱式內連接
使用where條件來消除無用的數據
查詢語句示例:
1 # 查詢所有字段 2 SELECT * FROM employe,department WHERE employe.`dep_id` = department.`id`; 3 4 # 查詢部分字段 5 SELECT 6 employe.`NAME`,employe.`id`,department.`dep_name` 7 FROM 8 employe,department 9 WHERE 10 employe.`dep_id` = department.`id`;
顯示內連接
select 字段列表 from 表名1 (inner) join 表名2 on 條件;
語法示例:
1 # 查詢全部字段 2 SELECT * FROM employe JOIN department ON employe.`dep_id` = department.`id`; 3 4 SELECT * FROM employe INNER JOIN department ON employe.`dep_id` = department.`id`; 5 6 # 查詢部分字段語法 7 SELECT 8 employe.`NAME`,employe.`id`,department.`dep_name` 9 FROM 10 employe JOIN department 11 ON 12 employe.`dep_id` = department.`id`;
外連接查詢
左外連接
語法
select 字段列表 from 表1 left (outer)join 表2 on 條件;查詢的是左表(表1)所有獲取左表所有記錄,即使右表沒有對應匹配的記錄
左(外)連接,左表(a_table)的記錄將會全部表示出來,而右表(b_table)只會顯示符合搜索條件的記錄。右表記錄不足的地方均為NULL
交集指的是:符合條件的字段則就稱為交集
1 SELECT * FROM employe LEFT JOIN department ON employe.`dep_id` = department.`id`;
右外連接
select 字段列表 from 表1 right【outer】 join 表2 on 條件;查詢的是右表(表2)獲取右表所有記錄,即使左表沒有對應匹配的記錄
1 SELECT * FROM employe RIGHT JOIN department ON employe.`dep_id` = department.`id`;
子查詢
查詢中嵌套查詢,稱嵌套查詢為子查詢
1,子查詢的結果是單行單列的:子查詢可以作為條件,使用運算符去判斷。運算符:>,>=,<,<=,=
2,子查詢的結果是多行單列的:子查詢可以作為條件,使用運算符IN來判斷
3,子查詢的結果是多行多列的:子查詢可以作為一個虛擬表參與查詢
4,any和all與比較運算符
4,Exists:判斷返回的結果為T或者F
聯合查詢
多表查詢大例子

1 -- 部門表 2 CREATE TABLE dept ( 3 id INT PRIMARY KEY PRIMARY KEY, -- 部門id 4 dname VARCHAR(50), -- 部門名稱 5 loc VARCHAR(50) -- 部門所在地 6 ); 7 8 -- 添加4個部門 9 INSERT INTO dept(id,dname,loc) VALUES 10 (10,'教研部','北京'), 11 (20,'學工部','上海'), 12 (30,'銷售部','廣州'), 13 (40,'財務部','深圳'); 14 15 16 17 -- 職務表,職務名稱,職務描述 18 CREATE TABLE job ( 19 id INT PRIMARY KEY, 20 jname VARCHAR(20), 21 description VARCHAR(50) 22 ); 23 24 -- 添加4個職務 25 INSERT INTO job (id, jname, description) VALUES 26 (1, '董事長', '管理整個公司,接單'), 27 (2, '經理', '管理部門員工'), 28 (3, '銷售員', '向客人推銷產品'), 29 (4, '文員', '使用辦公軟件'); 30 31 32 33 -- 員工表 34 CREATE TABLE emp ( 35 id INT PRIMARY KEY, -- 員工id 36 ename VARCHAR(50), -- 員工姓名 37 job_id INT, -- 職務id 38 mgr INT , -- 上級領導 39 joindate DATE, -- 入職日期 40 salary DECIMAL(7,2), -- 工資 41 bonus DECIMAL(7,2), -- 獎金 42 dept_id INT, -- 所在部門編號 43 CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id), 44 CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id) 45 ); 46 47 -- 添加員工 48 INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 49 (1001,'孫悟空',4,1004,'2000-12-17','8000.00',NULL,20), 50 (1002,'盧俊義',3,1006,'2001-02-20','16000.00','3000.00',30), 51 (1003,'林沖',3,1006,'2001-02-22','12500.00','5000.00',30), 52 (1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20), 53 (1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30), 54 (1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30), 55 (1007,'劉備',2,1009,'2001-09-01','24500.00',NULL,10), 56 (1008,'豬八戒',4,1004,'2007-04-19','30000.00',NULL,20), 57 (1009,'羅貫中',1,NULL,'2001-11-17','50000.00',NULL,10), 58 (1010,'吳用',3,1006,'2001-09-08','15000.00','0.00',30), 59 (1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20), 60 (1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30), 61 (1013,'小白龍',4,1004,'2001-12-03','30000.00',NULL,20), 62 (1014,'關羽',4,1007,'2002-01-23','13000.00',NULL,10); 63 64 65 66 -- 工資等級表 67 CREATE TABLE salarygrade ( 68 grade INT PRIMARY KEY, -- 級別 69 losalary INT, -- 最低工資 70 hisalary INT -- 最高工資 71 ); 72 73 -- 添加5個工資等級 74 INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 75 (1,7000,12000), 76 (2,12010,14000), 77 (3,14010,20000), 78 (4,20010,30000), 79 (5,30010,99990); 80 81 -- 需求: 82 83 -- 1.查詢所有員工信息。查詢員工編號,員工姓名,工資,職務名稱,職務描述 84 SELECT 85 t1.`id`, 86 t1.`ename`, 87 t1.`salary`, 88 t2.`jname`, 89 t2.`description` 90 FROM 91 emp t1,job t2 92 WHERE 93 t1.`job_id`=t2.`id`; 94 95 96 -- 2.查詢員工編號,員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置 97 SELECT 98 t1.`id`, 99 t1.`ename`, 100 t1.`salary`, 101 t2.`jname`, 102 t2.`description`, 103 t3.`dname`, 104 t3.`loc` 105 FROM 106 emp t1,job t2,dept t3 107 WHERE 108 t1.`job_id`=t2.`id` AND t1.`dept_id` = t3.`id`; 109 110 111 112 -- 3.查詢員工姓名,工資,工資等級 113 SELECT 114 t1.ename, 115 t1.`salary`, 116 t2.`grade` 117 FROM 118 emp t1,salarygrade t2 119 WHERE 120 -- t1.`salary`=<t2.`hisalary` and t1.`salary`>=t2.`losalary` 121 t1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`; 122 123 124 125 -- 4.查詢員工姓名,工資,職務名稱,職務描述,部門名稱,部門位置,工資等級 126 SELECT 127 t1.`ename`, 128 t1.`salary`, 129 t2.`jname`, 130 t2.`description`, 131 t3.`dname`, 132 t3.`loc`, 133 t4.`grade` 134 FROM 135 emp t1,job t2,dept t3,salarygrade t4 136 WHERE 137 t1.`job_id` = t2.`id` AND 138 t1.`dept_id` = t3.`id` AND 139 t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary`; 140 141 142 143 -- 5.查詢出部門編號、部門名稱、部門位置、部門人數 144 SELECT 145 t1.`id`, 146 t1.`dname`, 147 t1.`loc`, 148 t2.t3 149 FROM 150 dept t1,( SELECT dept_id,COUNT(id) t3 FROM emp GROUP BY dept_id) t2 151 152 WHERE 153 t1.`id`=t2.dept_id; 154 155 156 157 -- 6.查詢所有員工的姓名及其直接上級的姓名,沒有領導的員工也需要查詢 158 SELECT 159 t2.`ename`, 160 t2.`mgr`, 161 t1.`ename`, 162 t1.id 163 FROM 164 emp t1,emp t2 165 WHERE 166 t1.`id`=t2.`mgr`; 167 168 169 -- 自關聯映射 起別名 170 SELECT 171 t1.`ename`, 172 t2.`ename` 173 174 FROM 175 emp t1 176 LEFT JOIN emp t2 177 ON t1.`mgr`=t2.`id`
視圖
視圖是從一個或者幾個基本表或者視圖中導出的虛擬表,是從現有基表中抽取若干子集組成用戶的“專用表”,這種構造方式必須使用SQL中的SELECT語句來實現。
使用視圖具有如下優點。
(1)簡化對數據的操作。
(2)自定義數據。
(3)數據集中顯示。
(4)導入和導出數據。
(5)合並分割數據。
(6)安全機制。
創建視圖
在SQL中,使用CREATE VIEW語句創建視圖,其語法格式如下:
1 CREATE [OR REPLACE] VIEW <視圖名> [(字段名[,…])] 2 AS SELECT語句 3 [WITH CHECK OPTION];
例:在數據庫D_sample中定義視圖查詢學生的姓名、課程名稱和成績

1 use D_sample; 2 3 create view v1 4 as 5 select 姓名,課程名稱,成績 6 from student a,course b,sc c 7 where a.學號=c.學號 and b.課程號=c.課程號;
更新視圖
在SQL語句中,使用ALTER VIEW語句修改視圖,其語法格式如下:
1 ALTER VIEW <視圖名> [(字段名[,…])] 2 AS SELECT語句 3 [WITH CHECK OPTION];
例:修改上例中的視圖v1。

1 alter view v1 2 as select 學號,姓名 from student;
刪除視圖
在SQL中,使用DROP VIEW語句刪除視圖,其語法格式如下:
1 DROP VIEW {視圖名}[,…];
例:刪除視圖v1。

1 drop view v1;
-------------------