题目13

https://www.nowcoder.com/practice/72ca694734294dc78f513e147da7821e?tpId=82&tqId=29765&tPage=1&rp=&ru=/ta/sql&qru=/ta/sql/question-ranking
题目描述
从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);

图片说明

题解:

/* 解法1:*/
SELECT title, COUNT(title) AS t 
FROM titles
GROUP BY title 
HAVING t >= 2
/* 解法2:这里的count对任意一个属性计数都可以,改成to_date也能通过,其他属性都可以*/
select title, count(emp_no) as t
from titles
group by title
having t >= 2

一点笔记:
1、通过Group By分组
2、通过Having控制分组条件。having在group后。


题目14:

https://www.nowcoder.com/practice/c59b452f420c47f48d9c86d69efdff20?tpId=82&tqId=29766&tPage=1&rp=&ru=%2Fta%2Fsql&qru=%2Fta%2Fsql%2Fquestion-ranking
题目描述
从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。
注意对于重复的emp_no进行忽略。(其实是去重)

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:参考上题,对emp_no也可以通过,但是本题多一个去重*/
SELECT title, COUNT(DISTINCT emp_no) AS t 
FROM titles
GROUP BY title 
HAVING t >= 2
/* 解法2:这里子查询的emp_no和title不能颠倒*/
select title , count(title) as t 
from (select distinct emp_no,title from titles)
group by title 
having t >= 2;

题目15:

https://www.nowcoder.com/practice/a32669eb1d1740e785f105fa22741d5c?tpId=82&tqId=29767&tPage=1&rp=&ru=%2Fta%2Fsql&qru=%2Fta%2Fsql%2Fquestion-ranking
题目描述
查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列

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`));

图片说明

题解:

/* 解法1:其实最好用<>来表示不等于*/
select * from employees
where emp_no % 2 = 1
and last_name != 'Mary'
order by hire_date desc
/* 解法2:*/
select  emp_no, birth_date, first_name, last_name, gender, hire_date 
from employees
where emp_no % 2 = 1
and last_name != 'Mary'
order by hire_date desc

题目16:

https://www.nowcoder.com/practice/c8652e9e5a354b879e2a244200f1eaae?tpId=82&tqId=29768&tPage=1&rp=&ru=%2Fta%2Fsql&qru=%2Fta%2Fsql%2Fquestion-ranking
题目描述
统计出当前各个title类型对应的员工当前(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);

图片说明

题解:

/* 解法1:*/
SELECT t.title,avg(s.salary) AS avg
FROM salaries s ,titles t
where s.emp_no = t.emp_no
AND s.to_date = '9999-01-01'
AND t.to_date = '9999-01-01'
GROUP BY title
/* 解法2:不使用where,用join将表联结,则配合使用on*/
SELECT t.title,avg(s.salary)
FROM salaries as s INNER JOIN titles as t
ON s.emp_no = t.emp_no
AND s.to_date = '9999-01-01'
AND t.to_date = '9999-01-01'
GROUP BY title

一点笔记:where 是建表前先筛选,having是建表后再判断


题目17:

https://www.nowcoder.com/practice/8d2c290cc4e24403b98ca82ce45d04db?tpId=82&tqId=29769&tPage=1&rp=&ru=%2Fta%2Fsql&qru=%2Fta%2Fsql%2Fquestion-ranking
题目描述
获取当前(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`));

图片说明

题解:

/* 解法1:在不考虑有薪水相同的员工的情况下。降序排序,跳过1个,取1个*/
select emp_no,salary
from salaries
where to_date = '9999-01-01'
order by salary desc limit 1,1 
/* 解法2:在考虑有薪水相同的员工的情况下,选择薪水倒数*/
SELECT emp_no, salary
FROM salaries
WHERE salary = (SELECT distinct salary
                FROM salaries
                WHERE to_date = '9999-01-01'
                GROUP BY salary
                ORDER BY salary DESC LIMIT 1,1 )  
/* 解法3:考虑方式和解法2一样,写法不同*/
select emp_no, salary 
from salaries
where to_date = '9999-01-01' 
and salary = (select distinct salary from salaries order by salary desc limit 1,1)

一点总结:distinct必须放在开头
select id, distinct name from A; --会提示错误,因为distinct必须放在开头


题目18:

https://www.nowcoder.com/practice/c1472daba75d4635b7f8540b837cc719?tpId=82&tqId=29770&tPage=1&rp=&ru=%2Fta%2Fsql&qru=%2Fta%2Fsql%2Fquestion-ranking
题目描述
查找当前薪水(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`));

图片说明

题解:

/* 解法1:*/
SELECT e.emp_no, s1.salary, e.last_name, e.first_name
FROM employees e, salaries s1, salaries s2
WHERE e.emp_no = s1.emp_no
    AND s1.to_date = '9999-01-01'
    AND s2.to_date = '9999-01-01'
    AND s1.salary <= s2.salary
GROUP BY s1.emp_no
HAVING COUNT(DISTINCT s2.salary)=2
/* 解法2:*/
select e.emp_no,s.salary,e.last_name,e.first_name
from employees e join salaries s 
on e.emp_no=s.emp_no 
and  s.to_date='9999-01-01'
and s.salary = (
     select s1.salary
     from salaries s1 join salaries s2 
     on s1.salary<=s2.salary 
     and s1.to_date='9999-01-01' 
     and s2.to_date='9999-01-01'
     group by s1.salary
     having count(distinct s2.salary)=2
 )

一点总结:Part2的最后一题也是有难度,为什么每次都是最后一题难,唉。ORDER BY 语句用于根据指定的列对结果集进行排序。本题不让用排序。可以看到,这里将salaries表使用了两次,为s1和s2。而薪水第二多,意思就是只有一个人比他多,这样只要用salary表内连接,再分组,组内条数等于1的那条记录,就正好是第二多。如果要找第三多,那就让having count(*)=2就行了,只有两个人比那个人多。(假如说s1 和s2是 100 98 98 96 则 s1.100关联s2.100 s1.98关联s2.100 s2.98 s2.98 ,那么98对应的记录就是3条,去重后就是2条,而2条就以为着98第2大,只比100小)