習題 1.Homework01 (1) D -- 沒有在別名上加引號(ps:別名的as可以省略) (2) B -- 判斷null或非空不能用不等於號 (3) C 2.Homework02 寫出查看dept表和emp表的結構的sql語句 使用簡單查詢語句完成 顯示所有部門名稱 顯示所有雇員名及其全年收 ...
習題
1.Homework01
(1) D -- 沒有在別名上加引號(ps:別名的as可以省略)
(2) B -- 判斷null或非空不能用不等於號
(3) C
2.Homework02
-
寫出查看dept表和emp表的結構的sql語句
-
使用簡單查詢語句完成
- 顯示所有部門名稱
- 顯示所有雇員名及其全年收入 13月(工資+補助),並指定列別名“年收入”
-
限制查詢數據
- 顯示工資超過2850的雇員的姓名和工資
- 顯示工資不在1500到2850之間的員工名和工資
- 顯示編號為7566的雇員姓名及所在的部門編號
- 顯示部門10和30中工資超過1500的員工名及工資
- 顯示無管理者的雇員名及崗位
-
排序數據
- 顯示在1991-2-1到1991-5-1之間雇用的員工名,崗位以及雇用日期,並以雇用日期進行排序
- 顯示獲得補助的所有員工名,工資以及補助,並以工資降序進行排序
練習
-- 2.寫出查看dept表和emp表的結構的sql語句
DESC dept;
DESC emp;
-- 3.使用簡單查詢語句完成
-- 3.1 顯示所有部門名稱
SELECT dname FROM dept;
-- 3.2 顯示所有雇員名及其全年收入 13月(工資+補助),並指定列別名“年收入”
SELECT ename,(sal+IFNULL(comm ,0.0))*13 AS '年收入' FROM emp;
-- 4.限制查詢數據
-- 4.1顯示工資超過2850的雇員的姓名和工資
SELECT ename,sal FROM emp
WHERE sal>2850;
-- 4.2顯示工資不在1500到2850之間的員工名和工資
SELECT ename,sal FROM emp
WHERE sal>2850 OR sal<1500;
-- 4.3顯示編號為7566的雇員姓名及所在的部門編號
SELECT ename,deptno FROM emp
WHERE empno=7566;
-- 4.4顯示部門10和30中工資超過1500的員工名及工資
SELECT ename,sal FROM emp
WHERE deptno IN (10,30) AND sal >1500;
-- 4.5顯示無管理者的雇員名及崗位
SELECT ename,job FROM emp
WHERE mgr IS NULL;
-- 5.排序數據
-- 5.1顯示在1991-2-1到1991-5-1之間雇用的員工名,崗位以及雇用日期,
-- 並以雇用日期進行排序
SELECT ename,job,hiredate FROM emp
WHERE hiredate>='1991-02-01' AND hiredate<='1991-05-01'
ORDER BY hiredate;
-- 顯示獲得補助的所有員工名,工資以及補助,並以工資降序進行排序
SELECT ename,sal,comm FROM emp
WHERE comm IS NOT NULL
ORDER BY sal DESC;
3.Homework03
根據emp表寫出正確的sql
- 選擇部門30中的所有員工
- 列出所有辦事員(CLERK)的姓名,編號和部門編號
- 找出佣金高於薪金的員工
- 找出佣金高於薪金60%的員工
- 找出部門10中所有經理(MANAGER)和部門20中的所有辦事員(CLERK)的詳細資料
- 找出部門10中所有經理(MANAGER),部門20中的所有辦事員(CLERK),還有既不是經理又不是辦事員但其薪金大於或等於2000的所有員工的詳細資料
- 找出收取佣金的員工的不同工作
- 找出不收取佣金或收取佣金低於100的員工
- 找出各月倒數第三天受雇的所有員工
- 找出早於12年前受雇的員工
- 以首字母小寫的方式顯示所有員工的姓名
- 顯示正好為5個字元的員工的姓名
練習
SELECT * FROM emp;
-- 1. 選擇部門30中的所有員工
SELECT * FROM emp
WHERE deptno = 30;
-- 2. 列出所有辦事員(CLERK)的姓名,編號和部門編號
SELECT ename,empno,deptno FROM emp
WHERE job = 'CLERK';
-- 3. 找出佣金高於薪金的員工
SELECT ename FROM emp
WHERE IFNULL(comm,0)>sal;
-- 4. 找出佣金高於薪金60%的員工
SELECT ename FROM emp
WHERE IFNULL(comm,0)>(sal*0.6);
-- 5. 找出部門10中所有經理(MANAGER)和部門20中的所有辦事員(CLERK)的詳細資料
SELECT * FROM emp
WHERE (deptno = 10 AND job= 'MANAGER')OR
(deptno = 20 AND job= 'CLERK');
-- 6. 找出部門10中所有經理(MANAGER),部門20中的所有辦事員(CLERK),
-- 還有既不是經理又不是辦事員但其薪金大於或等於2000的所有員工的詳細資料
SELECT * FROM emp
WHERE (deptno = 10 AND job= 'MANAGER')OR
(deptno = 20 AND job= 'CLERK')OR
(job NOT IN ('MANAGER','CLERK') AND sal>=2000);
-- 7. 找出收取佣金的員工的不同工作
SELECT DISTINCT job FROM emp
WHERE comm IS NOT NULL;
-- 8. 找出不收取佣金或收取佣金低於100的員工
SELECT ename FROM emp
WHERE comm IS NULL OR IFNULL(comm,0) <100;
-- 9. 找出各月倒數第三天受雇的所有員工
-- 關於最後一天 last_day(日期)可以返回該日期所在月份的最後一天
SELECT * FROM emp
WHERE LAST_DAY(hiredate)-2 = hiredate;
-- 10. 找出早於12年前受雇的員工
SELECT * FROM emp
WHERE hiredate < DATE_SUB(NOW(),INTERVAL 12 YEAR);
-- 11. 以首字母小寫的方式顯示所有員工的姓名
-- 先截取首字母,將其小寫 LCASE (LEFT(ename,1))
-- 再截取剩下的字母 RIGHT(ename, (LENGTH(ename)-1))
-- 將兩者拼起來 CONCAT
SELECT CONCAT(LCASE(LEFT(ename,1)),RIGHT(ename, (LENGTH(ename)-1))) FROM emp
-- 或者
SELECT CONCAT( LCASE(LEFT(ename,1)) ,SUBSTRING(ename,2)) FROM emp;
-- 12. 顯示正好為5個字元的員工的姓名
SELECT ename FROM emp
WHERE ename LIKE '_____';
-- 或者
SELECT ename FROM emp
WHERE LENGTH(ename)=5;
4.Homework04
根據emp員工表,寫出正確的sql語句
- 顯示不帶有R的員工的姓名
- 顯示所有員工姓名的前三個字元
- 顯示所有員工的姓名,用a替換所有的A
- 顯示滿10年服務年限的員工的姓名和受雇日期
- 顯示員工的詳細資料,按姓名排序
- 顯示員工的姓名和受雇日期,根據其服務年限,將最老的員工排在最前面
- 顯示所有的員工的姓名,工作和薪金,按工作降序排序,若工作相同則按薪金排除
- 顯示所有員工的姓名,加入公司的年份和月份,按受雇日期所在月排序,若月份相同則將最早年份的員工排在最前面
- 顯示在一個月為30天的情況所有員工的日薪金,忽略餘數
- 找出在(任何年份的)2月受聘的所有員工
- 對於每個員工,顯示其加入公司的天數
- 顯示姓名欄位的任何位置包含A的所有員工的姓名
- 以年月日的方式顯示所有員工的服務年限(大概)
練習
-- 根據emp員工表,寫出正確的sql語句
SELECT * FROM emp;
-- 13. 顯示不帶有R的員工的姓名
SELECT ename FROM emp
WHERE ename NOT LIKE '%R%';
-- 14. 顯示所有員工姓名的前三個字元
SELECT LEFT(ename,3) FROM emp;
-- 15. 顯示所有員工的姓名,用a替換所有的A
SELECT REPLACE(ename,'A','a') FROM emp;
-- 16. 顯示滿10年服務年限的員工的姓名和受雇日期
SELECT ename,hiredate FROM emp
WHERE (DATEDIFF(NOW(),hiredate)/365)>10;
-- 17. 顯示員工的詳細資料,按姓名排序
SELECT * FROM emp
ORDER BY ename;
-- 18. 顯示員工的姓名和受雇日期,根據其服務年限,將最老的員工排在最前面
SELECT ename,hiredate FROM emp
ORDER BY hiredate;
-- 19. 顯示所有的員工的姓名,工作和薪金,按工作降序排序,若工作相同則按薪金排序
SELECT ename,job,sal FROM emp
ORDER BY job DESC,sal;
-- 20. 顯示所有員工的姓名,加入公司的年份和月份,
-- 按受雇日期所在月排序,若月份相同則將最早年份的員工排在最前面
SELECT ename,CONCAT(YEAR(hiredate),'-',MONTH(hiredate))FROM emp
ORDER BY MONTH(hiredate),YEAR(hiredate);
-- 21. 顯示在一個月為30天的情況所有員工的日薪金,忽略餘數
SELECT ename,FLOOR(sal/30) FROM emp
WHERE LAST_DAY(hiredate) LIKE '____-__-30';
-- 22. 找出在(任何年份的)2月受聘的所有員工
SELECT * FROM emp
WHERE hiredate LIKE '____-02-__';
-- 23. 對於每個員工,顯示其加入公司的天數
SELECT ename,DATEDIFF(NOW(),hiredate) FROM emp;
-- 24. 顯示姓名欄位的任何位置包含A的所有員工的姓名
SELECT ename FROM emp
WHERE ename LIKE '%A%';
-- 25. 以年月日的方式顯示所有員工的服務年限(大概)
SELECT ename,
(DATEDIFF(NOW(),hiredate)-DATEDIFF(NOW(),hiredate)%365)/365 AS '年',
(DATEDIFF(NOW(),hiredate)%365-DATEDIFF(NOW(),hiredate)%365%31)/31 AS '月',
DATEDIFF(NOW(),hiredate)%31 AS '天'
FROM emp
-- 或者
SELECT ename,
FLOOR((DATEDIFF(NOW(),hiredate)/365)) AS '年',
FLOOR(DATEDIFF(NOW(),hiredate)%365/31) AS '月',
DATEDIFF(NOW(),hiredate)%31 AS '天'
FROM emp
5.Homework05
根據emp員工表,dept部門表,工資=薪金+佣金,寫出正確的sql
- 列出至少有一個員工的所有部門
- 列出薪金比Smith多的所有員工
- 列出受雇日期晚於其直接上級的所有員工
- 列出部門名稱和這些部門的員工信息,同時列出那些沒有員工的部門
- 列出所有CLERK(辦事員)的姓名及其部門名稱
- 列出最低薪金大於1500的各種工作
- 列出在部門SALES(銷售部)工作的員工的姓名
- 列出薪金高於公司平均薪金的所有員工
-- 根據emp員工表,dept部門表,工資=薪金+佣金,寫出正確的sql
SELECT * FROM emp;
SELECT * FROM dept;
SELECT * FROM salgrade;
-- 1. 列出至少有一個員工的所有部門
SELECT DISTINCT dname FROM emp,dept
WHERE emp.deptno=dept.deptno;
-- 或者
SELECT COUNT(*) AS c ,deptno
FROM emp
GROUP BY deptno
HAVING c > 1;
-- 2. 列出薪金比Smith多的所有員工
-- 先查出Smith的sal
-- 然後其他的員工的sal>smith.sal
SELECT ename FROM emp
WHERE sal>(SELECT sal FROM emp WHERE ename='SMITH');
-- 3. 列出受雇日期晚於其直接上級的所有員工
-- 先把emp表當做是兩張表,worker , leader (自連接)
-- 條件1. emp.hiredate>d.hiredate 條件2.emp.mgr=d.empno
SELECT worker.ename AS '員工名',worker.hiredate AS '員工入職時間',
leader.ename AS '上級名',leader.hiredate AS '上級入職時間'
FROM emp AS worker, emp AS leader
WHERE worker.mgr=leader.empno AND worker.hiredate>leader.hiredate;
-- 4. 列出部門名稱和這些部門的員工信息,同時列出那些沒有員工的部門
-- 這裡因為需要顯示所有部門,需要使用外連接
SELECT dname,emp.* FROM emp RIGHT JOIN dept
ON emp.deptno=dept.deptno ;
-- 5. 列出所有CLERK(辦事員)的姓名及其部門名稱
SELECT ename,dname FROM emp,dept
WHERE job='CLERK' AND emp.deptno=dept.deptno;
-- 6. 列出最低薪金大於1500的各種工作
SELECT DISTINCT job FROM emp
WHERE job NOT IN
(SELECT job FROM emp
WHERE sal <1500);
-- 或者
-- 查詢各個部門的最低工資
-- 使用having子句進行過濾
SELECT MIN(sal) AS min_sal ,job
FROM emp
GROUP BY job
HAVING min_sal > 1500;
-- 7. 列出在部門SALES(銷售部)工作的員工的姓名
SELECT ename FROM emp,dept
WHERE emp.deptno = dept.deptno AND dname = 'SALES';
-- 8. 列出薪金高於公司平均薪金的所有員工
SELECT ename FROM emp
WHERE sal>(SELECT AVG(sal) FROM emp)
6.Homework06
根據emp員工表,dept部門表,工資=薪金+佣金,寫出正確的sql
- 列出與SCOTT從事相同工作的所有員工
- 列出薪金高於,在部門30工作的所有員工的薪金,的員工姓名和薪金
- 列出在每個部門工作的員工數量,平均工資和平均服務期限
- 列出所有員工的姓名,部門名稱和工資
- 列出所有部門的詳細信息和部門人數
- 列出各種工作的最低工資
- 列出MANAGER(經理)的最低薪金
- 列出所有員工的年工資,按年薪從低到高排序
SELECT * FROM emp;
SELECT * FROM dept;
SELECT * FROM salgrade;
-- 1. 列出與SCOTT從事相同工作的所有員工
SELECT * FROM emp
WHERE job=(SELECT job FROM emp WHERE ename='SCOTT');
-- 2. 列出薪金高於,在部門30工作的所有員工的薪金,的員工姓名和薪金
-- 先查詢出30號部門的最高工資
SELECT ename ,sal FROM emp
WHERE sal>(SELECT MAX(sal) FROM emp
WHERE deptno = 30)
-- 3. 列出在每個部門工作的員工數量,平均工資和平均服務期限
SELECT COUNT(*) AS '員工數量',
deptno,
AVG(sal+IFNULL(comm,0)) AS '部門平均工資',
AVG(DATEDIFF(NOW(),hiredate)/365) AS '平均服務期限年'
FROM emp
GROUP BY deptno
-- 4. 列出所有員工的姓名,部門名稱和工資
SELECT ename,dname,sal+IFNULL(comm,0) FROM emp,dept
WHERE emp.deptno= dept.deptno
-- 5. 列出所有部門的詳細信息和部門人數
-- 先得到各個部門的平均人數
SELECT dept.*, `all`
FROM dept
LEFT JOIN
(SELECT COUNT(*) AS `all`,deptno
FROM emp
GROUP BY emp.deptno) AS temp
ON dept.deptno=temp.deptno
-- 6. 列出各種工作的最低工資
SELECT job ,MIN(sal+IFNULL(comm,0))AS '最低工資' FROM emp
GROUP BY job;
-- 7. 列出MANAGER(經理)的最低薪金
SELECT MIN(sal+IFNULL(comm,0))AS '最低工資' FROM emp
WHERE job= 'MANAGER';
-- 8. 列出所有員工的年工資,按年薪從低到高排序
SELECT ename,(sal+IFNULL(comm,0))*12 AS '年工資' FROM emp
ORDER BY (sal+IFNULL(comm,0));
7.Homework07
設學校環境如下:一個系有若幹個專業,每一個專業一年只招一個班,每個班有若幹個學生。先要建立關於系、學生和班級的資料庫,關係模式為:
班CLASS (班號classid,專業名subject,系名deptname,入學年份enrolltime,人數num)
學生STUDENT(學號studentid,姓名name,年齡age,班號classid)
系DEPARTMENT(系號departmentid,系名deptname)
試用sql語言完成下麵功能:
-
建表,在定義中要求聲明:
- 每個表的主外鍵
- deptname是唯一約束
- 學生姓名不能為空
-
插入如下數據
DEPARTMENT( 001,數學; 002,電腦; 003,電腦; 004,電腦; 005,電腦; )
CLASS( 101,軟體,電腦,1995,20; 102,微電子,電腦,1996,30; 111,無機化學,化學,1995,29; 112,高分子化學,化學,1996,25; 121,統計數學,數學,1995,20; 131,現代語言,中文,1996,20; 141,國際貿易,經濟,1997,30; 142,國際金融,經濟,1996,14; )
STUDENT( 8101,張三,18,101; 8102,錢四,16,121; 8103,王玲,17,131; 8105,李飛,19,102; 8109,趙四,18,141; 8110,李可,20,142; 8201,張飛,18,111; 8302,周瑜,16,112; 8203,王亮,17,111; 8305,董慶,19,102; 8409,趙龍,18,101; 8510,李麗,20,142; )
-
完成以下查詢功能
- 找出所有姓李的學生
- 列出所有開設超過1個專業的系的名字
- 列出人數大於等於30的系的編號和名字
-
學校又新增了一個物理系,編號為006
-
學生張三退學,請更新相關的表
-- 試用sql語言完成下麵功能:
-- 1. 建表,在定義中要求聲明:
-- - 每個表的主外鍵
-- - deptname是唯一約束
-- - 學生姓名不能為空
-- 系DEPARTMENT(系號departmentid,系名deptname)
CREATE TABLE DEPARTMENT(
departmentid VARCHAR(32) PRIMARY KEY,
deptname VARCHAR(32) UNIQUE NOT NULL
);
-- 班CLASS (班號classid,專業名subject,系名deptname,入學年份enrolltime,人數num)
CREATE TABLE CLASS(
classid INT PRIMARY KEY,
`subject` VARCHAR(32) NOT NULL DEFAULT '',
deptname VARCHAR(32),
enrolltime INT NOT NULL DEFAULT 2000,
num INT NOT NULL DEFAULT 0,
FOREIGN KEY (deptname) REFERENCES DEPARTMENT(deptname)
);
-- 學生STUDENT(學號studentid,姓名name,年齡age,班號classid)
CREATE TABLE hsp_STUDENT(
studentid INT PRIMARY KEY,
`name` VARCHAR(32) NOT NULL DEFAULT '',
age INT NOT NULL DEFAULT 0,
classid INT,
FOREIGN KEY (classid) REFERENCES CLASS(classid)
);
-- 2. 插入如下數據
INSERT INTO DEPARTMENT VALUES('001','數學');
INSERT INTO DEPARTMENT VALUES('002','電腦');
INSERT INTO DEPARTMENT VALUES('003','化學');
INSERT INTO DEPARTMENT VALUES('004','中文');
INSERT INTO DEPARTMENT VALUES('005','經濟');
INSERT INTO CLASS VALUES(101,'軟體','電腦',1995,20);
INSERT INTO CLASS VALUES(102,'微電子','電腦',1996,30);
INSERT INTO CLASS VALUES(111,'無機化學','化學',1995,29);
INSERT INTO CLASS VALUES(112,'高分子化學','化學',1996,25);
INSERT INTO CLASS VALUES(121,'統計數學','數學',1995,20);
INSERT INTO CLASS VALUES(131,'現代語言','中文',1996,20);
INSERT INTO CLASS VALUES(141,'國際貿易','經濟',1997,30);
INSERT INTO CLASS VALUES(142,'國際金融','經濟',1996,14);
INSERT INTO hsp_STUDENT VALUES(8101,'張三',18,101);
INSERT INTO hsp_STUDENT VALUES(8102,'錢四',16,121);
INSERT INTO hsp_STUDENT VALUES(8103,'王玲',17,131);
INSERT INTO hsp_STUDENT VALUES(8105,'李飛',19,102);
INSERT INTO hsp_STUDENT VALUES(8109,'趙四',18,141);
INSERT INTO hsp_STUDENT VALUES(8110,'李可',20,142);
INSERT INTO hsp_STUDENT VALUES(8201,'張飛',18,111);
INSERT INTO hsp_STUDENT VALUES(8302,'周瑜',16,112);
INSERT INTO hsp_STUDENT VALUES(8203,'王亮',17,111);
INSERT INTO hsp_STUDENT VALUES(8305,'董慶',19,102);
INSERT INTO hsp_STUDENT VALUES(8409,'趙龍',18,101);
INSERT INTO hsp_STUDENT VALUES(8510,'李麗',20,142);
SELECT * FROM DEPARTMENT;
SELECT * FROM CLASS;
SELECT * FROM hsp_STUDENT;
-- 3. 完成以下查詢功能
-- 3.1 找出所有姓李的學生
SELECT * FROM hsp_STUDENT
WHERE `name` LIKE '李%';
-- 3.2 列出所有開設超過1個專業的系的名字
SELECT deptname,COUNT(*) AS nums FROM CLASS
GROUP BY deptname
HAVING nums > 1;
-- 3.3 列出人數大於等於30的系的編號和名字
-- 先查出每個系有多少人
-- 將上面的結果看成是一個臨時表,與DEPARTMENT表進行聯合查詢即可
SELECT temp.*,departmentid
FROM DEPARTMENT,
(SELECT SUM(num) AS nums,deptname
FROM CLASS
GROUP BY deptname
HAVING nums>=30) AS temp
WHERE DEPARTMENT.deptname=temp.deptname;
-- 4. 學校又新增了一個物理系,編號為006
INSERT INTO department VALUES('006','物理系');
-- 5. 學生張三退學,請更新相關的表
-- 使用事務處理
START TRANSACTION ;
-- 5.1張三所在的班級人數要減1
UPDATE class SET num=num-1
WHERE classid =(
SELECT classid
FROM hsp_STUDENT
WHERE `name` = '張三'
);
-- 5.2將張三從學生表中刪除
DELETE
FROM hsp_STUDENT
WHERE `name` = '張三';
-- 提交事務
COMMIT;