以下各个题目将用到上图的4个表,其关联关系如图所示。这个四个表中字段的具体情况参看如下内容:
EMPLOYEES(employee_id number(6) not null,first_namevarchar2(20),last_name varchar2(25) not null,email varchar2(25) notnull,phone_number varchar2(20),hire_date date not null,job_id varchar2(10) notnull,salary number(8,2),commission_pct number(2,2),manager_idnumber(6),department_id number(4))
DEPT(department_id number(4) not null,department_name varchar2(30) notnull,manager_id number(6),location_id number(4))
locations(location_id number(4) not null,city varchar2(20))
job_grades(grade_level varchar2(3),lowest_sal number,highest_salnumber)
1. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。job_grades(grade_level,lowest_sal,highest_sal)。显示JOB_GRADES表的结构。创建一个查询显示所有雇员的name、job、department name、salary 和 grade。
DESC JOB_GRADES
SELECT e.last_name, e.job_id, d.department_name, e.salary,j.grade_level FROM employees e, departments d, job_grades j WHEREe.department_id = d.department_id AND e.salary BETWEEN j.lowest_sal ANDj.highest_sal;
-- OR
SELECT e.last_name, e.job_id, d.department_name, e.salary,j.grade_level FROM employees e JOIN departments d ON (e.department_id =d.department_id) JOIN job_grades j ON (e.salary BETWEEN j.lowest_sal ANDj.highest_sal);
2. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。创建一个查询显示那些在雇员 Davies 之后入本公司工作的雇员的name 和 hire date。
SELECT e.last_name,e.hire_date
FROM employees e,employees davies
WHEREdavies.last_name = 'Davies'
AND davies.hire_date< e.hire_date
-- OR
SELECT e.last_name,e.hire_date
FROM employees e JOINemployees davies
ON (davies.last_name= 'Davies')
WHEREdavies.hire_date < e.hire_date;
3. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。显示所有雇员的 names 和 hire dates,他们在他们的经理之前进入本公司,连同他们的经理的名字和受雇日期一起显示。列标签分别为Employee、Emp Hired、Manager 和 Mgr Hired。
SELECT w.last_name,w.hire_date, m.last_name, m.hire_date FROM employees w, employees m WHEREw.manager_id = m.employee_id AND w.hire_date < m.hire_date;
-- OR
SELECT w.last_name,w.hire_date, m.last_name, m.hire_date
FROM employees w JOIN employees m
ON (w.manager_id = m.employee_id)
WHERE w.hire_date < m.hire_date;
4. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。显示所有雇员的最高、最低、合计和平均薪水,列标签分别为:Maximum、Minimum、Sum 和 Average。四舍五入结果为最近的整数
SELECTROUND(MAX(salary),0) "Maximum",
ROUND(MIN(salary),0)"Minimum",
ROUND(SUM(salary),0)"Sum",
ROUND(AVG(salary),0)"Average"
FROM employees;
5. 在4题基础上,显示每中工作类型的最低、最高、合计和平均薪水。
SELECT job_id,ROUND(MAX(salary),0) "Maximum",
ROUND(MIN(salary),0)"Minimum",
ROUND(SUM(salary),0)"Sum",
ROUND(AVG(salary),0)"Average"
FROM employees
GROUP BY job_id;
6. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。写一个查询显示每一工作岗位的人数。
SELECT job_id,COUNT(*)
FROM employees
GROUP BY job_id;
7. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。确定经理人数,不需要列出他们,列标签是 Number of Managers。提示:用MANAGER_ID 列决定经理号。
SELECT COUNT(DISTINCTmanager_id) "Number of Managers"
FROM employees;
8. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。写一个查询显示最高和最低薪水之间的差。列标签是 DIFFERENCE。
SELECT MAX(salary) - MIN(salary) DIFFERENCE
FROM employees;
9. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。显示经理号和经理付给雇员的最低薪水。排除那些经理未知的人。排除最低薪水小于等于 $6,000 的组。按薪水降序排序输出。
SELECT manager_id, MIN(salary)
FROM employees
WHERE manager_id ISNOT NULL
GROUP BY manager_id
HAVING MIN(salary)> 6000
ORDER BY MIN(salary)DESC;
10. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。DEPT(department_id,department_name,manager_id,location_id)。写一个查询显示每个部门的名字、地点、人数和部门中所有雇员的平均薪水。四舍五入薪水到两位小数。
SELECT d.department_name "Name", d.location_id"Location",
COUNT(*) "Numberof People",
ROUND(AVG(salary),2)"Salary"
FROM employees e,departments d
WHERE e.department_id= d.department_id
GROUP BYd.department_name, d.location_id;
11. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。创建一个查询显示雇员总数,和在 1995、1996、1997 和 1998受雇的雇员人数。创建适当的列标题。
SELECT COUNT(*)total,
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1995,1,0))"1 995",
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1996,1,0))"1 996",
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1997,1,0))"1 997",
SUM(DECODE(TO_CHAR(hire_date, 'YYYY'),1998,1,0))"1 998"
FROM employees;
12. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。创建一个混合查询显示工作岗位和工作岗位的薪水合计,并且合计部门 20、50、80 和 90 的工作岗位的薪水。给每列一个恰当的列标题。
SELECT job_id "Job",
SUM(DECODE(department_id , 20, salary)) "Dept 20",
SUM(DECODE(department_id , 50, salary)) "Dept 50",
SUM(DECODE(department_id , 80, salary)) "Dept 80",
SUM(DECODE(department_id , 90, salary)) "Dept 90",
SUM(salary)"Total"
FROM employees
GROUP BY job_id;
13. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。写一个查询显示与 Zlotkey 在同一部门的雇员的 last name 和 hire date,结果中不包括 Zlotkey。
SELECT last_name,hire_date
FROM employees
WHERE department_id =(SELECT department_id
FROM employees
WHERE last_name ='Zlotkey')
AND last_name<> 'Zlotkey';
14. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。创建一个查询显示所有其薪水高于平均薪水的雇员的雇员号和名字。按薪水的升序排序。
SELECT employee_id,last_name
FROM employees
WHERE salary >(SELECT AVG(salary)
FROM employees);
15. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。写一个查询显示所有工作在有任一雇员的名字中包含一个u 的部门的雇员的雇员号和名字
SELECT employee_id,last_name
FROM employees
WHERE department_idIN (SELECT department_id
FROM employees
WHERE last_name like'%u%');
16. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。DEPT(department_id,department_name,manager_id,location_id)。显示所有部门地点号(departmentlocation ID ) 是1700的雇员的lastname、departmentnumber 和jobID。
SELECT last_name,department_id, job_id
FROM employees
WHERE department_idIN (SELECT department_id
FROM departments
WHERE location_id =1700);
17. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。显示每个向 King 报告的雇员的名字和薪水。
SELECT last_name,salary
FROM employees
WHERE manager_id =(SELECT employee_id
FROM employees
WHERE last_name = 'King');
18. EMPLOYEES(employee_id,first_name,last_name,email,phone_number,hire_date,job_id,salary,commission_pct,manager_id,department_id)。DEPT(department_id,department_name,manager_id,location_id)。显示在Executive部门的每个雇员的departmentnumber、last name 和 job ID。
SELECT department_id, last_name, job_id
FROM employees
WHERE department_idIN (SELECT department_id
FROM departments
WHERE department_name= 'Executive');
19. 在15题基础上,查询显示所有收入高于平均薪水并且工作在有任一雇员的名字中带有一个u 的部门的雇员的 employeenumbers、last names 和 salaries。
SELECT employee_id, last_name, salary
FROM employees
WHERE department_idIN (SELECT department_id
FROM employees
WHERE last_name like'%u%')
AND salary >(SELECT AVG(salary)
FROM employees);
20. 创建一个称为EMPLOYEES_VU的视图,它基于EMPLOYEES表中的雇员号、雇员名和部门号。将雇员名的列标题改为EMPLOYEE。
CREATE OR REPLACE VIEW employees_vu AS
SELECT employee_id,last_name employee, department_id
FROM employees;
21. 在20题的基础上,显示 EMPLOYEES_VU 视图的内容。
SELECT *
FROM employees_vu;
22. 使用EMPLOYEES_VU视图,输入一个查询来显示所有的雇员名和部门号。
SELECT employee, department_id
FROM employees_vu;
23. 创建一个名为DEPT50视图,其中包含部门50中的所有雇员的雇员号、雇员名和部门号,视图的列标签为EMPNO、EMPLOYEE和DEPTNO。不允许通过视图将一个雇员重新分配到另一个部门。
CREATE VIEW dept50 AS
SELECT employee_idempno, last_name employee,
department_id deptno
FROM employees
WHERE department_id =50
WITH CHECK OPTIONCONSTRAINT emp_dept_50;
24. 在23题基础上,显示DEPT50视图的结构和内容。
DESCRIBE dept50
SELECT *
FROM dept50;
25. 创建一个名为SALARY_VU的视图,该视图基于所有雇员的名字、部门名、薪水和薪水级别。用EMPLOYEES、DEPARTMENTS和JOB_GRADES表,分别命名列标签为Employee、Department、Salary和Grade。
CREATE OR REPLACEVIEW salary_vu
AS
SELECT e.last_name"Employee",
d.department_name"Department",
e.salary"Salary",
j.grade_level"Grades"
FROM employees e,
departments d,
job_grades j
WHERE e.department_id= d.department_id
AND e.salary BETWEENj.lowest_sal and j.highest_sal;
26. 创建一个序列用于DEPT表的主键列,该序列从200开始,并且有最大值1000,序列的增量是10,序列的名字是DEPT_ID_SEQ。
CREATE SEQUENCE dept_id_seq
START WITH 200
INCREMENT BY 10
MAXVALUE 1000;
27. 写一个查询,显示下面关于序列的信息:序列名、最大值、增量大小和最后的值
SELECT sequence_name, max_value, increment_by, last_number
FROM user_sequences;
28. DEPT(department_id,department_name,manager_id,location_id)。写一个脚本插入两行到 DEPT 表中,并使用66题创建的序列来生成主键。
INSERT INTO dept
VALUES(dept_id_seq.nextval, 'Education');
29. 在 EMP 表中的外键列 DEPT_ID 上创建一个非唯一性索引。
CREATE INDEX emp_dept_id_idx ON emp(dept_id);