「牛客网SQL实战」| Day3

☺☺☺

Day3六道题

考查知识点
题号 知识点
1 GROUP BY分组;COUNT()统计个数;HAVING对GROUP BY 后的数据进行限制
2 DISTINCT去重
3 %求余;!=不等于
4 AVG()求平均值
5 limit x, y 分句表示: 跳过 x 条数据,读取 y 条数据
6 MAX()嵌套
一、从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t
  • 题目描述:

从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
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);

  • 分析:
    GROUP BY对title进行分组,COUNT()统计分组后每组的个数,HAVING来对每组个数进行限制
  • 代码:
SELECT title, COUNT(title) AS num
FROM titles
GROUP BY title
HAVING num>=2
二、从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。注意对于重复的emp_no进行忽略(即emp_no重复的title不计算,title对应的数目t不增加)。
  • 题目描述:

从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略(即emp_no重复的title不计算,title对应的数目t不增加)。
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);

  • 分析:
    这道题跟上一题前半部分一样,多了个对于重复的emp_no这个值,其title对应数目不增加。开始理解成了只要emp_no这个值重复就不计算title的个数了,理解有误。题目意思对于重复的emp_no在同一个title类之下只需要计算一次即可。
    使用DISTINCT对emp_no值去重,COUNT()统计出GROUP BY聚合之后每组的不重复emp_no值。
  • 代码:
SELECT title, COUNT(DISTINCT emp_no) AS t 
FROM titles
GROUP BY title 
HAVING t >= 2
三、查找employees表所有emp_no为奇数,且last_name不为Mary(注意大小写)的员工信息,并按照hire_date逆序排列
  • 题目描述:

查找employees表所有emp_no为奇数,且last_name不为Mary(注意大小写)的员工信息,并按照hire_date逆序排列(题目不能使用mod函数)
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));

  • 分析:
    居然才知道SQL里还能用!=(;д;)
  • 代码:
SELECT *
FROM employees
WHERE emp_no%2=1
AND last_name != 'Mary'
ORDER BY hire_date
DESC
四、统计出当前(titles.to_date=‘9999-01-01’)各个title类型对应的员工当前(salaries.to_date=‘9999-01-01’)薪水对应的平均工资。结果给出title以及平均工资avg
  • 题目描述:

统计出当前(titles.to_date=‘9999-01-01’)各个title类型对应的员工当前(salaries.to_date=‘9999-01-01’)薪水对应的平均工资。结果给出title以及平均工资avg。
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));
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);

  • 分析:
    avg求平均工资,where将量表链接对应。
  • 代码:
SELECT b.title, AVG(a.salary)
FROM salaries a, titles b
WHERE b.to_date='9999-01-01'
AND a.to_date='9999-01-01'
AND a.emp_no = b.emp_no
GROUP BY b.title
五、获取当前(to_date=‘9999-01-01’)薪水第二多的员工的emp_no以及其对应的薪水salary
  • 题目描述:

获取当前(to_date=‘9999-01-01’)薪水第二多的员工的emp_no以及其对应的薪水salary
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));

  • 分析:
    对salary大小倒序排列之后,用LIMIT x,y去除第二员工的薪水。
  • 代码:
SELECT emp_no, salary
FROM salaries
WHERE to_date='9999-01-01'
ORDER BY salary
DESC
LIMIT 1,1
六、查找当前薪水(to_date=‘9999-01-01’)排名第二多的员工编号emp_no、薪水salary、last_name以及first_name(不用order by实现)
  • 题目描述:

查找当前薪水(to_date=‘9999-01-01’)排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,你可以不使用order by完成吗
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));

  • 分析:
    先用max找到这个薪水最高的值,然后再找出薪水最高但是值小于之前计算出的最高值,就得到了薪水第二高的值。
    等于是一个MAX()嵌套。

还有一点注意:若工资相同要去重,但本题的方法刚好完美的避开了这个需要驱虫的过程,直接将重复值全部过滤掉了。

  • 代码:
SELECT a.emp_no, MAX(b.salary), a.last_name, a.first_name
FROM employees a, salaries b 
WHERE b.salary<(SELECT MAX(salary) FROM salaries)
AND b.to_date="9999-01-01"
AND a.emp_no = b.emp_no

或:

SELECT e.emp_no, MAX(s.salary) AS salary, e.last_name, e.first_name 
FROM employees AS e INNER JOIN salaries AS s 
ON e.emp_no = s.emp_no
WHERE s.to_date = '9999-01-01' 
AND s.salary NOT IN (SELECT MAX(salary) FROM salaries WHERE to_date = '9999-01-01')

你可能感兴趣的:(数据库,数据库)