Classic interview questions for oracle multi-table query

1. Cartesian product

  1. concept

Cartesian product refers to the Cartesian product, also known as direct product, of two sets X and Y in mathematics, expressed as X × Y , the first object is a member of X and the second object is One of the members of all possible ordered pairs of Y. [1]

To put it simply, each element of set X and each element of set B are combined in pairs, and the number of combinations is equal to the number of elements in set X * the number of elements in set Y.

  1. Plot of filtering out valid data from a Cartesian product
select * from emp e, dept d where e.deptno = d.deptno;

Schematic diagram of Cartesian product query

  1. some notes
  • As can be seen from the above figure, rows with different departments have no practical significance, and the appearance of simple Cartesian products is meaningless in most cases. If there is a Cartesian product or a small range, it means that the sql statement is probably wrong;
  • As can be seen from the above figure, the first Cartesian product of the two tables is eliminated one by one through the conditions, and a lot of invalid data will be generated in the middle, so try to filter the conditions before the Cartesian product is performed;

2. Introduction to the four connection methods [2]

  1. Inner join (table A inner join table B on condition)
    returns the matching data of table A (left table) and table B (right table);
  2. Left outer join (table A left join table B on condition)
    All records of table A (left table) are displayed, while table B (right table) will only display records that meet the conditions, and table B (right table) has insufficient records both are null;
  3. The result of right outer join (table A right join table B on condition)
    and left outer join is just the opposite. Based on table B (right table), it displays all records of table B (right table), and adds table A ( The left table) records that meet the conditions, and the places where the records in Table A (left table) are insufficient are all null;
  4. Full join (table A full join table B on condition)
    returns all rows in table A (left table) and table B (right table);

     

    Four connection methods.jpg

3. Detailed case explanation

Introduction to sql operating environment

  1. Database: oracle database 10g
  2. Visual development tool: PL/SQL Developer
  3. Source of table information: Oracle comes with tables emp table (employee table) and dept table (department table)
  4. The relationship between the employee table and the department table: one-to-many relationship (one employee belongs to one department, and one department has multiple employees)
  5. Two table content
    employee table:

    emp table jpg.jpg


    Department table:

    dept table jpg.jpg


    Salary registration form:

    salgrade.jpg

case

  1. Query the superior leader of each employee (query content: employee number, employee name, employee department number, employee salary, leader number, leader name, leader salary)
select
  e1.empno 雇员编号, e1.ename 雇员姓名, e1.deptno 雇员部门编号, e1.sal 雇员月薪, e1.mgr 雇员领导编号, e2.ename 领导名称, e2.sal 领导工资
from
  emp e1, emp e2
where
  e1.mgr = e2.empno(+);

search result:

Paste_Image.png


Idea: (+)The symbol represents the outreach table, which means the content that needs to be completed.

 

  1. On the basis of question 1, query the department corresponding to the employee
select
  e1.empno 雇员编号, e1.ename 雇员姓名, e1.deptno 雇员部门编号, e1.sal 雇员工资,
  d1.dname 员工部门名称, e1.sal 雇员月薪, e1.mgr 领导编号, 
  e2.ename 领导名称, e2.sal 领导工资
from
  emp e1, emp e2, dept d1
where
  e1.mgr = e2.empno(+)
and
  d1.deptno(+) = e1.deptno

**search result: **

 

Paste_Image.png

 

The red line is the effect of the left outer join.

  1. On the basis of question 3, query the leader's department name
  • Method 1 using oracle
select
  e1.empno 雇员编号, e1.ename 雇员姓名, 
  e1.deptno 雇员部门编号, d1.dname 员工部门名称, e1.sal 雇员月薪, 
  e1.mgr 领导编号, e2.ename 领导名称, d2.dname 领导部门名称, e2.sal 领导工资
from
  emp e1, emp e2, dept d1, dept d2
where
  e1.mgr = e2.empno(+)
and
  d1.deptno(+) = e1.deptno
and
  d2.deptno(+) = e2.deptno;

operation result:

Paste_Image.png

 

  • Method 2 Use native sql query
select 
  e1d1.雇员编号, e1d1.雇员姓名, e1d1.雇员部门编号, e1d1.员工部门名称, 
  e1d1.雇员月薪, e1d1.领导编号, 
  e2e1d2.领导姓名, e2e1d2.领导月薪, e2e1d2.领导部门编号, e2e1d2.领导部门名称
from (select
        e1.empno 雇员编号, e1.ename 雇员姓名, 
        e1.deptno 雇员部门编号, d1.dname 员工部门名称, e1.sal 雇员月薪, 
        e1.mgr 领导编号
      from emp e1 left join dept d1 on
        e1.deptno = d1.deptno) e1d1 
left join (select
               e2e1.领导的编号 领导的编号, e2e1.领导姓名 领导姓名, 
               e2e1.领导月薪 领导月薪, d2.deptno 领导部门编号, d2.dname 领导部门名称
             from (select
                   distinct e2.empno 领导的编号,e2.ename 领导姓名, 
                   e2.sal 领导月薪, e2.deptno 领导部门编号
                   from emp e2 left join emp e1 on
                     e1.mgr = e2.empno) e2e1 left join dept d2 on
               e2e1.领导部门编号 = d2.deptno) e2e1d2 on
  e1d1.领导编号 = e2e1d2.领导的编号;

search result:

Paste_Image.png


Thought: I just want to pretend, not to scare people! ! ! Native sql can indeed do the same function, but it is too complicated. It uses 5 tables and keeps left outer joins.

 

  1. Check out each employee number, name, department name, salary grade and the name and salary grade of his superior
select
  e.empno 员工编号, e.ename 员工姓名, d.dname 员工部门名称, 
  s.grade 员工工资等级, e2.ename 领导姓名, s2.grade 领导工资等级 
from
  emp e, dept d, salgrade s, emp e2, salgrade s2 
where
      e.deptno = d.deptno(+)
    and
      e.sal between s.losal and s.hisal
    and
      e.mgr = e2.empno(+)
    and
      e2.sal between s2.losal and s2.hisal;

search result:

Paste_Image.png


Idea: The first employee table ( emp e) and the second department table ( dept d) are queried under the condition ( e.deptno = d.deptno(+)), and the result is used as a new table, with the third employee salary grade table ('salgrade s') in the condition (' e. sal between s.losal and s.hisal'), the result is another new table, and the fourth leader table ('emp e2') is queried under the condition ('emp e2'), and the result is another new table. Zhang Xin table and the fifth leader salary grade table ('salgrade s2') are queried under the condition ('e2.sal between s2.losal and s2.hisal'), remember the final result.

 

  1. Find employees with higher salaries than SCOTT
select * from emp where sal > 
(select sal from emp where ename = 'SCOTT');

operation result:

Paste_Image.png


Idea: Use the method of subquery. First query the salary of SCOTT employees ( select sal from emp where ename = 'SCOTT'), and then use the result as part of the conditional expression of another SQL statement to query.

 

  1. Query employees whose job title is manager and whose salary is higher than that of employee No. 7782
  • Method 1 (subquery):
select * from emp where job = 'MANAGER' and sal > (select sal from emp where empno = 7782);
  • Method 2 (set operation):
select * from emp where job = 'MANAGER'
intersect -- 交集
select * from emp where sal > (select sal from emp where empno = 7782);

search result:

Paste_Image.png


Ideas: Method 1 is basically the same as the previous question, except that one more condition is added. Method 2 uses the methods of intersection, union, and minus of sets to obtain results; set operations also have preconditions, two result sets, the number of columns is equal and the corresponding column data The operation can only be performed if the type is the same.

 

  1. Query the result that the minimum wage of the department is greater than the minimum wage of the department No. 30
select deptno, min(sal) from emp 
group by deptno having 
  min(sal) > (select min(sal) from emp where deptno = '30');

search result:

Paste_Image.png


Idea: First query the minimum wage of department No. 30 select min(sal) from emp where deptno = '30', then query the minimum wage select deptno, min(sal) from emp group by deptnoof the department, and splicing the two query statements according to the requirements of the topic.

 

  1. Find out the employees in the same department and position as SCOTT (excluding SCOTT himself)
select * from emp where 
  (job, deptno) = 
  (select job, deptno from emp where ename = 'SCOTT') 
  and ename != 'SCOTT';

operation result:

Paste_Image.png


Idea: Use the method of multi-column subquery.

 

  1. Topic 9: Query the employee information corresponding to the minimum wage of each department (including the department name)
select e.*, d.dname from emp e, dept d 
where e.sal in
  (select min(sal) from emp group by deptno) 
  and e.deptno = d.deptno;

search result:

Paste_Image.png


Idea: first query the minimum wage select min(sal) from emp group by deptnoof each department, and then query the employee information corresponding to the minimum wage

select * from emp where e.sal in 各部门最低工资结果集, and then inner join the query result set (new table) and the dept table, and remove the invalid records to get the result.

 

  1. Query employees who are not leaders
select * from emp 
where empno not in
  (select distinct mgr from emp where mgr is not null);

search result:


Idea: Query the number of the leader of each employee select distinct mgr from emp where mgr is not null(the president has no superior leader, so it is null and should be excluded). In the query employee table, the employee number is not excluded from this result set select * from emp where empno not in 领导编号结果集, and the result is obtained.

 

  1. Question 11: Query the top three with the highest salary in the employee table
select t.*,rownum from (select * from emp order by sal desc) t where rownum < 4;

search result:

Paste_Image.png


Idea: select * from emp where rownum < 4 order by sal desc;The result cannot be obtained by the de method. The reason is that rownum is a pseudo column, which has been generated before the query condition and cannot be the condition of the query. The sorting result needs to be queried twice, and a new rownum can be used as the basis of the query condition. .

 

  1. On the basis of the previous question, query the information of the employees with the 4th to 6th salary
select * from
  (select ed.*, rownum r from
    (select * from emp order by sal desc) ed 
  where rownum < 7) t 
where t.r > 3

operation result:

Paste_Image.png


Idea: First sort the tables in descending order of sal select * from emp order by sal desc, then use the results as a temporary table to obtain the information and row numbers of the top 6 employees with salaries, select ed.*, rownum r from sal降序表 ed where rownum < 7and use the query results as another temporary table to query the data of 4 to 6 salaries select * from 前6名员工表 where t.r > 3; no Used select ed.*, rownum r from sal降序表 ed where rownum > 3 and rownum < 7because rownum does not support the greater-than operator.
** This question involves the idea of ​​oracle paging, and I will go deeper in the future when I have time**

 

  1. Find the employee whose salary is greater than the average salary of the department in the employee table
select * from emp e, (select deptno, avg(sal) avgsal 
from emp group by deptno) t 
where t.deptno = e.deptno and e.sal > t.avgsal;

search result:

Paste_Image.png


Ideas: First query the average salary of each department select deptno, avg(sal) avgsal from emp group by deptnoas a temporary table, select * from emp e, 各部门平均工资表 where t.deptno = e.deptno and e.sal > t.avgsaland then get the results.

 

  1. Count the number of employees hired each year
select to_char(hiredate, 'yyyy') 年份, count(*) 入职人数 from emp e 
group by to_char(hiredate, 'yyyy');

search result:

Paste_Image.png


Ideas: Use oracle's conversion function to convert the date type into a string type for sorting. ·to_char (date type, 'date format'), where the date format is generally expressed as 'yyyy-MM-dd HH-mi-ss', which can be used selectively.

 

  1. Convert the vertical table to a horizontal table on the basis of the previous question
select
  '入职人数' "年份",
  sum(decode(竖表.年份, '1980', 竖表.入职人数)) "1980",
  sum(decode(竖表.年份, '1981', 竖表.入职人数)) "1981",  
  sum(decode(竖表.年份, '1982', 竖表.入职人数)) "1982",
  sum(decode(竖表.年份, '1987', 竖表.入职人数)) "1987",
  sum(竖表.入职人数) "Total"
from (select to_char(hiredate, 'yyyy') 年份, count(*) 入职人数 
      from emp e group by to_char(hiredate, 'yyyy')) 竖表

operation result:

Paste_Image.png


Idea: The decode function is unique to oracle, and the method of use is decode (column name, content to be escaped, content to be escaped, content to be escaped, content to be escaped...), such as the select job,decode(job,'CLERK','业务员','SALESMAN','销售员','其它') from emprunning result:

Paste_Image.png


The sum function adds up the compiled columns, if there is no sum function the result is:

Paste_Image.png

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325363672&siteId=291194637