//很显然,需要对两张表进行连接查询 //where和innerjoin的效果是一样的,但是尽量用innerjoin性能好 SELECT s.*,d.dept_no FROM salaries s INNERJOIN dept_manager d ON s.emp_no = d.emp_no orderby emp_no
/* INNER JOIN 两边表同时有对应的数据,即任何一边缺失数据就不显示。 LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。 RIGHT JOIN 会读取右边数据表的全部数据,即便左边表无对应数据。*/ //这里当没有匹配项时要显示员工表的信息,所以用左连接 SELECT last_name,first_name,dept_no FROM employees e LEFTJOIN dept_emp d ON e.emp_no = d.emp_no
SQL7
查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t,现在给一张薪水表
1 2 3 4 5 6 7
//很显然,这里要求的是每个员工的薪水记录,所以要对员工分组聚合查询,groupby+count //并且需要对聚合后的结果进行筛选,需要使用having //小技巧:select后聚合的属性可起别名,用在having筛选中 SELECT emp_no,COUNT(emp_no) t FROM salaries GROUPBY emp_no HAVING t >15
SQL10
获取所有非manager的员工emp_no
1 2 3 4 5 6 7 8 9 10 11 12 13
//用左连接判断是否有员工不是领导 SELECT e.emp_no FROM employees e LEFTJOIN dept_manager d ON e.emp_no = d.emp_no WHERE d.emp_no ISNULL
//不包含用 NOTIN(...) SELECT emp_no FROM employees WHERE emp_no NOTIN( SELECT emp_no FROM dept_manager )
SQL11
获取所有员工当前的manager
注意两个细节
题目中要求当前/现在,需要把to_date固定,员工走了或者领导走了都不显示
如果员工是经理则不显示,意思是两个属性不相等
两张表肯定要连接,那么基于哪个属性连接呢? 这里要求的是员工对应的部门领导,所以要对部门连接
1 2 3 4 5
SELECT e.emp_no,m.emp_no FROM dept_emp e INNERJOIN dept_manager m ON e.dept_no = m.dept_no WHERE e.emp_no != m.emp_no && e.to_date ='9999-01-01'&& m.to_date ='9999-01-01'
SQL12
获取每个部门中当前员工薪水最高的相关信息 经典问题:select非聚合字段
错误示范:
1 2 3 4 5 6 7 8
//错误示范 SELECT dept_no,d.emp_no,MAX(salary) maxSalary FROM dept_emp d INNERJOIN salaries s ON d.emp_no=s.emp_no GROUPBY dept_no HAVING d.dept_no ='9999-01-01' ORDERBY dept_no
//先求每个部门最高薪水的表,然后求部门、员工、薪水的表,两张表连接查询 SELECT t1.dept_no,t1.emp_no, maxSalary FROM ( SELECT d1.emp_no,dept_no,salary FROM dept_emp d1 INNERJOIN salaries s1 ON d1.emp_no=s1.emp_no WHERE d1.to_date='9999-01-01'AND s1.to_date='9999-01-01' ) t1 INNERJOIN ( SELECT dept_no,MAX(salary) maxSalary FROM dept_emp d2 INNERJOIN salaries s2 ON d2.emp_no = s2.emp_no WHERE d2.to_date='9999-01-01'AND s2.to_date='9999-01-01' GROUPBY dept_no ) t2 ON t1.dept_no=t2.dept_no AND t1.salary=t2.maxSalary ORDERBY t1.dept_no
SQL16
统计各个title类型对应的员工薪水和平均工资
这题考查:对分组聚合后的结果进行排序
1 2 3 4 5 6 7
SELECT title,AVG(salary) FROM titles t INNERJOIN salaries s ON t.emp_no=s.emp_no WHERE t.to_date='9999-01-01'AND s.to_date='9999-01-01' GROUPBY title ORDERBYAVG(salary)
SQL17
获取薪水第二多的员工的编号和对应的薪水
注意:多个员工的薪水为第二多的薪水的情况
1 2 3 4 5 6 7 8 9 10
SELECT emp_no,salary FROM salaries WHERE to_date='9999-01-01'AND salary=( SELECTDISTINCT salary FROM salaries WHERE to_date='9999-01-01' ORDERBY salary DESC LIMIT 1OFFSET1 ) ORDERBY emp_no ASC
SELECT e.emp_no,salary,last_name,first_name FROM employees e INNERJOIN salaries s ON e.emp_no=s.emp_no WHERE salary=( SELECTMAX(salary) FROM salaries WHERE salary < ( SELECTMAX(salary) FROM salaries WHERE to_date='9999-01-01' ) AND to_date='9999-01-01' ) AND to_date='9999-01-01'
SQL19
查找所有员工的last_name、first_name和dept_name
题目要求没有分配部门的员工显示部门名为NULL,显然是左连接
1 2 3
SELECT last_name,first_name,dept_name FROM employees e LEFTJOIN dept_emp de ON e.emp_no=de.emp_no LEFTJOIN departments d ON de.dept_no=d.dept_no