Practice 1 Solutions

advertisement
8-adv_SQL_eval_inges2_1_sols
Practice 1 Solutions
1. Display the department that has no employees.
SQL>
2
3
4
5
6
SELECT
FROM
MINUS
SELECT
FROM
WHERE
deptno,dname
dept
e.deptno,d.dname
emp e,dept d
e.deptno = d.deptno;
2. Find the job that was filled in the last half of 1981 and the same job that was filled during
the same period in 1982.
SQL>
2
3
4
5
6
7
SELECT job
FROM
emp
WHERE hiredate BETWEEN '01-JUN-81' AND '30-DEC-81'
INTERSECT
SELECT job
FROM
emp
WHERE hiredate BETWEEN '01-JUN-82' AND '30-DEC-82';
Practice 1 Solutions (continued)
4. Produce a list of jobs for departments 10, 30, and 20 in that order. Display job and
department number.
COLUMN dummy NOPRINT
SELECT
FROM
WHERE
UNION
SELECT
FROM
WHERE
UNION
SELECT
FROM
WHERE
ORDER BY
/
job,deptno,'x' dummy
emp
deptno = 10
job,deptno,'y'
emp
deptno = 30
job,deptno,'z'
emp
deptno = 20
3
5. List the department number for departments without the job title ANALYST.
SQL>
2
3
4
5
6
SELECT
FROM
MINUS
SELECT
FROM
WHERE
deptno
dept
deptno
emp
job = 'ANALYST';
8-adv_SQL_eval_inges2_1_sols
6. List all job titles in department 10 and 20 that do not occur in both departments.
SQL>
2
3
4
5
6
7
8
9
10
11
SELECT
FROM
WHERE
MINUS
job
emp
deptno in (20,10)
(SELECT job
FROM
emp
WHERE
deptno = 10
INTERSECT
SELECT job
FROM
emp
WHERE
deptno = 20);
Practice 2 Solutions
2. Find all employees who are not a supervisor.
a. Do this using the EXISTS operator first.
SQL> SELECT outer.ename
2 FROM
emp outer
3 WHERE EXISTS (SELECT empno
4
FROM
emp inner
5
WHERE inner.mgr = outer.empno);
b. Can this be done using the IN operator? Why, or why not?
SQL> SELECT outer.ename
2 FROM
emp outer
3 WHERE outer.empno NOT IN (SELECT inner.mgr
FROM
emp inner);
This alternative solution is not a good one. The subquery picks up a NULL value, and
hence the entire query returns no rows. The reason is that all conditions that compare a
NULL value, result in NULL. So, whenever NULL values are likely to be part of the value
set, do not use NOT IN as a substitute for NOT EXISTS.
Practice 2 Solutions (continued)
3. Write a query to find all employees who make more than the average salary in their
department. Display employee number, salary, department number, and the average
salary for the department. Sort by average salary.
SQL>
2
3
4
5
6
7
SELECT
FROM
WHERE
AND
e.ename ename, e.sal salary,
e.deptno deptno, AVG(a.sal) dept_avg
emp e, emp a
e.deptno = a.deptno
e.sal > (SELECT AVG(sal)
FROM
emp
WHERE deptno = e.deptno)
8-adv_SQL_eval_inges2_1_sols
8
9
GROUP BY e.ename, e.sal, e.deptno
ORDER BY AVG(a.sal);
4. Write a query to display employees who earn less than half the average salary in their
department.
SQL> SELECT
2 FROM
3 WHERE
4
5
6
ename
emp outer
outer.sal < (SELECT avg(inner.sal/2)
FROM
emp inner
WHERE inner.deptno =
outer.deptno);
5. Write a query to display employees who have one or more co-workers in their department
with later hiredates but higher salaries.
SQL> SELECT
2 FROM
3 WHERE
4
5
6
7
8
ename
emp outer
EXISTS (SELECT
FROM
WHERE
AND
AND
inner.empno
emp inner
inner.deptno = outer.deptno
inner.hiredate >
outer.hiredate
inner.sal > outer.sal);
3. Hierarchical Retrieval
2. Write a hierarchical query showing employee number, manager number, and employee
name for all employees who are two levels below JONES (employee 7566).
SQL>
2
3
4
5
SELECT empno, mgr, level, ename
FROM
emp
WHERE LEVEL = 3
CONNECT BY mgr = PRIOR empno
START WITH empno = 7566;
4. Generate Scripts to Generate Scripts
1.
Write a SQL script file to drop all objects (tables, views, indexes, sequences, synonyms
and so on) that you own. The output shown is just a guideline.
SET HEADING OFF ECHO OFF FEEDBACK OFF TERMOUT OFF
SET PAGESIZE 0
SPOOL dropall.sql
SELECT
'drop ' || OBJECT_TYPE || ' ' || OBJECT_NAME || ';'
FROM
user_objects
ORDER BY object_type
/
SPOOL off
8-adv_SQL_eval_inges2_1_sols
SET HEADING ON ECHO ON FEEDBACK ON TERMOUT ON
SET PAGESIZE 24
2. Write a SQL script to produce a CREATE TABLE statement for every table you own.
Hints:
• The data dictionary view USER_TAB_COLUMNS contains all the information that you
need.
• Assume that you have only relational tables in your database and no LOBs.
• Write three SELECT statements combined with the UNION operator.
– The first one builds the first part of the CREATE TABLE statement.
– The second one picks up the column definition for all columns but the last
column.
– The third one picks up the column definition for the last column.
4. Generate Scripts to Generate Scripts (continued)
SET FEEDBACK OFF ECHO OFF HEAD OFF
SET PAGESIZE 9999
COLUMN sort1 NOPRINT
COLUMN sort2 NOPRINT
BREAK ON sort1 skip1
SPOOL c:\create.sql
SELECT DISTINCT table_name sort1,
0
sort2,
'CREATE TABLE ' || table_name ||' ('
FROM
user_tab_columns
UNION
SELECT table_name sort1,
column_id sort2,
' '||
column_name ||
DECODE(data_type,'DATE',' DATE',
'LONG',' LONG',
'CHAR',' CHAR('||data_length||')',
'VARCHAR2',' VARCHAR2('||data_length||')',
'NUMBER',
DECODE(data_precision,null,' NUMBER',
' NUMBER('||data_precision||','||
data_scale||') '),
'*****Invalid datatype******')||
DECODE(nullable,'N',' NOT NULL',null)||','
FROM
user_tab_columns c
WHERE column_id < (SELECT MAX(column_id)
FROM
user_tab_columns
WHERE
table_name = c.table_name)
UNION
SELECT table_name sort1,
column_id sort2,
8-adv_SQL_eval_inges2_1_sols
' '||
column_name ||
DECODE(data_type,'DATE',' DATE',
'LONG',' LONG',
'CHAR',' CHAR('||data_length||')',
'VARCHAR2',' VARCHAR2('||data_length||')',
'NUMBER',
DECODE(data_precision,null,' NUMBER',
' NUMBER('||data_precision||','||
data_scale||') '),
'*****Invalid datatype*****')||
DECODE(nullable,'N',' NOT NULL',null)||')
/'
FROM
user_tab_columns c
WHERE column_id = (SELECT max(column_id)
FROM
user_tab_columns
WHERE
table_name = c.table_name)
ORDER BY 1,2
/
SPOOL OFF
COLUMN sort1 CLEAR
COLUMN sort2 CLEAR
SET FEEDBACK ON HEAD ON ECHO ON
SET PAGESIZE 24
Download