mysql面试题及其解题思路(一)

首先创建数据库表:1.员工信息表

CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `first_name` varchar(14) NOT NULL, `last_name` varchar(16) NOT NULL, `gender` char(1) NOT NULL, `hire_date` date NOT NULL, PRIMARY KEY (`emp_no`));
CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));
备注:
员工信息表、员工number、员工出生日期、员工的first/last name、员工的性别、员工入职时间、主键为员工number
``
**2.员工所在部门表**
``

CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL, `dept_no` char(4) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`));

3.薪水表

CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`));

4经理所在部门表

CREATE TABLE `dept_manager` ( `dept_no` char(4) NOT NULL, `emp_no` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`dept_no`));

5.title表

CREATE TABLE IF NOT EXISTS "titles" ( `emp_no` int(11) NOT NULL, `title` varchar(50) NOT NULL, `from_date` date NOT NULL, `to_date` date DEFAULT NULL);

1.查找最晚入职的员工信息
用到的表:员工信息表

select * from employees where hire_date = (select max(hire_date) from employees) 用到的知识: 1.嵌套sql,先查出最晚入职时间嵌套进where条件中 2.max函数:返回一列中的最大值

2.查找入职员工时间排名倒数第三的员工所有信息
用到的表:员工信息表

SELECT *
FROM
employees 
WHERE hire_date = (SELECT hire_date FROM employees ORDER BY hire_date DESC LIMIT 2,1);
用到的知识:
1.嵌套sql,先查出排名倒数第三的时间
2.order by 语句:对指定列进行排序。默认升序 使用  desc是降序
3.limit m,n语句:表示从第m条开始,取n条数据

3查找所有已经分配部门的员工的last_name和first_name
用到的表:员工信息表,员工所在部门表

select e.last_name,e.first_name,d.dept_no from employees e inner join dept_emp d on e.emp_no=d.emp_no ;
用到的知识:
1.inner join :
在表中存在至少一个匹配时,INNER JOIN 关键字返回行。如果为空则不会返回这些行,查找已经分配部门员工的name,dept_no为空的不会返回。

4.查找所有员工的last_name和first_name以及对应部门编号dept_no,也包括展示没有分配具体部门的员工

select e.last_name,e.first_name,d.dept_no from employees e left join dept_emp d on e.emp_no=d.emp_no ;
用到的知识:
left join:
会读取左边数据表的全部数据,即便右边表无对应数据。
因为左边表有first和last name所以可以查出所有信息。

5.查找所有员工入职时候的薪水情况,给出emp_no以及salary, 并按照emp_no进行逆序
用到的表:员工信息表,薪水表

select e.emp_no,s.salary from employees e,salaries s  where e.emp_no=s.emp_no
and  e.hire_date = s.from_date 
order by e.emp_no desc;
用到的知识:
order by语句要写在where语句之后,否则不通过
每一个员工可能有多个薪水,薪水涨跌,主键是联合主键emp_no和from_date,所以要有条件限制

6.查找薪水涨幅超过15次的员工号emp_no以及其对应的涨幅次数t
用到的表:工资表

select emp_no ,count(emp_no) as t 
from salaries 
group by emp_no having t>15;
用到的知识点:
1.count(列名):COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入)
SUM、AVG、COUNT、MAXMIN 这些聚合函数忽略空值,而COUNT(*) 不忽略.
2.group by 语句:
配合聚合函数使用:如sum,不能仅仅写像group by emp_no而不用聚合函数,因为一个emp_no对应多条数据 详见我的博客:http://blog.csdn.net/peanutwzk/article/details/79247318
3group by having 语句
HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集。HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足。

7.找出所有员工当前(to_date=’9999-01-01’)具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
用到的表:薪水表

select  salary from salaries 
where to_date='9999-01-01'
  group by salary
   order by salary desc ;
   用到的知识点:
   排除重复数据,可以用distinct也可以用 group  by  但是用 group by在数据量大的时候会更好

8.获取所有非manager的员工emp_no
用到的表:dept_manager和员工表

方法一:使用NOT IN选出在employees但不在dept_manager中的emp_no记录
SELECT emp_no FROM employees WHERE emp_no NOT IN (SELECT emp_no FROM dept_manager) 用到的知识:not in 不过推荐用exists:用in会导致想不到的错误 SELECT emp_no FROM employees WHERE NOT exists (SELECT emp_no FROM dept_manager);
in和exists的区别见我的博客:
方法二:先使用LEFT JOIN连接两张表,再从此表中选出dept_no值为NULL对应的emp_no记录
SELECT employees.emp_no FROM employees LEFT JOIN dept_manager ON employees.emp_no = dept_manager.emp_no WHERE dept_no IS NULL SELECT emp_no FROM employees WHERE NOT exists (SELECT emp_no FROM dept_manager);

9.从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。

select title,count(title)as t from titles group by title having t>=2;
这道题考察的知识点应该是group by having 上面已经提到过了

10查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
用到的表“员工基本信息表”

select * from employees 
where emp_no%2=1 
and last_name!='Mary'
order by hire_date desc
考察的知识点:判断是否为奇数 取余数,看是否为 1 mysql用 % oracle用 mod(numer1,number2)
降序排列 order by desc

11.查找员工编号emp_now为10001其自入职以来的薪水salary涨幅值growth

用到的表:工资表
SELECT ( (SELECT salary FROM salaries WHERE emp_no = 10001 ORDER BY to_date DESC LIMIT 1) - (SELECT salary FROM salaries WHERE emp_no = 10001 ORDER BY to_date ASC LIMIT 1) ) AS growth;
用到的知识:
1.select语句中时可以嵌套其他的select2.利用排序来查出最早的工资和最晚的工资

12.查找所有员工自入职以来的薪水涨幅情况,给出员工编号emp_noy以及其对应的薪水涨幅growth,并按照growth进行升序

SELECT sCurrent.emp_no, (sCurrent.salary-sStart.salary) AS growth FROM (SELECT s.emp_no, s.salary FROM employees e LEFT JOIN salaries s ON e.emp_no = s.emp_no WHERE s.to_date = '9999-01-01') AS sCurrent LEFT JOIN salaries s ON e.emp_no = s.emp_no WHERE s.from_date = e.hire_date) AS sStart ON sCurrent.emp_no = sStart.emp_no ORDER BY growth;
11题和12题可以结合起来看有什么异同
查出来的结果可以是表,并且可以自己把这个表命名并且作为条件

你可能感兴趣的:(面试)