mysql解题思路_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、MAX 和MIN 这些聚合函数忽略空值,而COUNT(*) 不忽略.

2.group by 语句:

配合聚合函数使用:如sum,不能仅仅写像group by emp_no而不用聚合函数,因为一个emp_no对应多条数据 详见我的博客:http://blog.csdn.net/peanutwzk/article/details/79247318

3、group 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语句中时可以嵌套其他的select的

2.利用排序来查出最早的工资和最晚的工资

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题可以结合起来看有什么异同

查出来的结果可以是表,并且可以自己把这个表命名并且作为条件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值