"Silicon Valley" MySQL system course has a total of 6 days. The following introduces the learning content of day 3, which mainly involves advanced 6 join queries (sql99 syntax), advanced 7 sub-queries and advanced 8 paging queries. It’s full of dry goods. It may be a little longer as the course progresses, but there will be gains after reading it, so let’s start now.
table of Contents
Advanced 6: Connect query (sql99 syntax)
Advanced 6: Connect query (sql99 syntax)
grammar:
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名
on 连接条件
【where 筛选条件】#该版本可以区分连接条件和筛选条件
【group by 分组】
【having 筛选条件】
【order by 排序列表】
classification:
1. Internal connection (★): inner
2. External connection
左外(★):left 【outer】
Right outside (★): right 【outer】
Full outside: full【outer】
3. Cross connection: cross
Code analysis:
1. Internal connection
grammar:
select 查询列表
from 表1 别名
inner join 表2 别名
on 连接条件;
classification:
Equivalent connection conditions are equivalent
Non-equivalent connection conditions are non-equivalent
Self-connection According to the variables in Table 1, connect to Table 1
Features:
①Add sort ORDER BY, group GROUP BY, filter HAVING/WHERE
② inner can be omitted
③The filter condition is placed after where, and the connection condition is placed after on, which improves the separation and is easy to read
④The inner join connection and the equivalent join effect in the sql92 grammar are the same, both of which query the intersection of multiple tables
1. Equivalent connection
#1、等值连接
#案例1.查询员工名、部门名--可以调换表的顺序-属性`department_id`是唯一的。
SELECT last_name,department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id` = d.`department_id`;
SELECT last_name,department_name
FROM departments d
JOIN employees e
ON e.`department_id` = d.`department_id`;
#案例2.查询名字中包含e的员工名和工种名(添加筛选)
SELECT last_name,job_title
FROM employees e
INNER JOIN jobs j
ON e.`job_id`= j.`job_id`
WHERE e.`last_name` LIKE '%e%';
#案例3. 查询部门个数>3的城市名和部门个数(添加分组+筛选)
#①查询每个城市的部门个数-添加别名
#②在①结果上筛选满足条件的
SELECT city,COUNT(*) 部门个数
FROM departments d
INNER JOIN locations l
ON d.`location_id` = l.`location_id`
GROUP BY city
HAVING COUNT(*)>3; #添加筛选条件
#案例4.查询哪个部门的员工个数>3的部门名和员工个数,并按个数降序(添加排序)
#①查询每个部门的员工个数
SELECT COUNT(*),department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id` = d.`department_id`
GROUP BY department_name
#② 在①结果上筛选员工个数>3的记录,并排序
SELECT COUNT(*) 个数,department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name
HAVING COUNT(*)>3
ORDER BY COUNT(*) DESC; #按照降序排列
#案例5.查询员工名、部门名、工种名,并按部门名降序(添加三表连接)
#n表连接需要至少n-1个连接条件
SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN departments d ON e.`department_id` = d.`department_id`
INNER JOIN jobs j ON e.`job_id` = j.`job_id`
ORDER BY department_name DESC;
2. Non-equivalent connection
#案例1:查询员工的工资级别
SELECT salary,grade_level
FROM employees e
JOIN job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;
#案例2:查询工资级别的个数>20的个数,并且按工资级别降序
SELECT COUNT(*),grade_level
FROM employees e
JOIN job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`
GROUP BY grade_level
HAVING COUNT(*)>20
ORDER BY grade_level DESC;
3. Self-connection
#案例1:查询员工的名字、上级的名字
SELECT e.last_name,m.last_name
FROM employees e
JOIN employees m
ON e.`manager_id`= m.`employee_id`;
#案例2:查询姓名中包含字符k的员工的名字、上级的名字
SELECT e.last_name,m.last_name
FROM employees e
JOIN employees m
ON e.`manager_id`= m.`employee_id`
WHERE e.`last_name` LIKE '%k%';
Two, external connection
Application scenario : used to query records that are in one table but not in another table
Features :
1. The query result of the outer join is all the records in the main table
If there is a match from the table, the matched value is displayed
If there is no match from the table, it will display null
Outer join query result = inner join result + records in the master table but not in the slave table
2. Left outer join, left join is the main table on the left
Right outer join, right join is the main table on the right
3. The same effect can be achieved by swapping the order of the two tables between the left outer and the right outer
4. Full outer join = result of inner join + what is in table 1 but not in table 2 + what is in table 2 but not in table 1
#引入:查询男朋友 不在男神表的的女神名
SELECT * FROM beauty;
SELECT * FROM boys;
#左外连接-查找没有女神的男神名
SELECT b.*,bo.*
FROM boys bo
LEFT OUTER JOIN beauty b
ON b.`boyfriend_id` = bo.`id`
WHERE b.`id` IS NULL;
#左外连接-查找没有男朋友的女神名
SELECT b.name,bo.*
FROM beauty b
LEFT OUTER JOIN boys bo
ON b.`boyfriend_id` = bo.`id`
WHERE bo.`id` IS NULL;
#右外连接-查找没有男朋友的女神名
SELECT b.name,bo.*
FROM boys bo
RIGHT OUTER JOIN beauty b
ON b.`boyfriend_id` = bo.`id`
WHERE bo.`id` IS NULL;
#案例1:查询哪个部门没有员工
#左外
SELECT d.*,e.employee_id
FROM departments d
LEFT OUTER JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
#右外
SELECT d.*,e.employee_id
FROM employees e
RIGHT OUTER JOIN departments d
ON d.`department_id` = e.`department_id`
WHERE e.`employee_id` IS NULL;
#全外(不执行,因为MySQL不支持)
USE girls;
SELECT b.*,bo.*
FROM beauty b
FULL OUTER JOIN boys bo
ON b.`boyfriend_id` = bo.id;
#交叉连接
SELECT b.*,bo.*
FROM beauty b
CROSS JOIN boys bo;
sql92 and sql99 big pk
①Function: sql99 supports more
②Readability: sql99 realizes the separation of connection conditions and screening conditions, which is more readable
[Case explanation] Outer join-multi-table join
#一、查询编号>3的女神的男朋友信息,如果有则列出详细,如果没有,用null填充
#注意审题,beauty表左连接
SELECT bo.*,b.name,b.id
FROM boys bo
LEFT OUTER JOIN beauty b
ON bo.id = b.boyfriend_id
WHERE b.id > 3;
SELECT b.id,b.name,bo.*
FROM beauty b
LEFT OUTER JOIN boys bo
ON b.`boyfriend_id` = bo.`id`
WHERE b.`id` > 3;
#二、查询哪个城市没有部门----等价于部门id为空
USE myemployees;
SELECT city #, COUNT(department_name)
FROM locations l
LEFT OUTER JOIN departments d
ON l.`location_id` = d.`location_id`
GROUP BY city
HAVING COUNT(department_name)=0;
SELECT city #,d.*
FROM departments d
RIGHT OUTER JOIN locations l
ON d.`location_id`=l.`location_id`
WHERE d.`department_id` IS NULL;
#三、查询部门名为SAL或IT的员工信息
USE myemployees;
#最好还是显示d.`department_id`,因为不是一一对应department_name
SELECT e.*,d.department_name,d.`department_id`
FROM employees e
FROM employees e
LEFT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE department_name = SAL OR department_name = IT;
SELECT e.*,d.department_name,d.`department_id`
FROM departments d
LEFT JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE d.`department_name` IN('SAL','IT');
SELECT * FROM departments
WHERE `department_name` IN('SAL','IT');
Advanced 7: Subquery
meaning:
The select statement that appears in other statements (not just the query statement) is called a subquery or inner query
External query statement, called main query or external query
classification:
By the position where the subquery appears:
1. Behind select:
Only supports scalar subqueries
2. After from:
Support table subquery
3. Behind where or having: ★
Scalar quantum query (single line) √
Lie sub query (multiple rows) √
Row subquery
4. Behind exists (related subquery)
Table subquery
According to the number of rows and columns of the result set:
Scalar sub-query (the result set has only one row and one column)
Column query (the result set has only one column and multiple rows)
Row subquery (the result set has one row and multiple columns)
Table subquery (the result set is generally multi-row and multi-column)
Code analysis:
One, behind where or having
1. Standard sub-query (single-line sub-query)
2. Column sub-query (multi-line sub-query)
3. Row subquery (multiple columns and multiple rows)
Features:
①The subquery is placed in parentheses
②Subqueries are generally placed on the right side of the conditions
③ Scalar quantum query, generally used with single-line operators
> < >= <= = <>
Lie sub-queries, generally used with multi-line operators
in、any/some、all
④ The execution of the subquery takes precedence over the execution of the main query, and the conditions of the main query use the results of the subquery
1. Scalar quantum query★
#案例1:谁的工资比 Abel 高?
#①查询Abel的工资
SELECT salary
FROM employees
WHERE last_name = 'Abel'
#②查询员工的信息,满足 salary>①结果
SELECT *
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name = 'Abel'
);
#案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id 和工资
#①查询141号员工的job_id
SELECT job_id
FROM employees
WHERE employee_id = 141
#②查询143号员工的salary
SELECT salary
FROM employees
WHERE employee_id = 143
#③查询员工的姓名,job_id 和工资,要求job_id=①并且salary>②
SELECT last_name,job_id,salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 141
) AND salary>(
SELECT salary
FROM employees
WHERE employee_id = 143
);
#案例3:返回公司工资最少的员工的last_name,job_id和salary
#①查询公司的 最低工资
SELECT MIN(salary)
FROM employees
#②查询last_name,job_id和salary,要求salary=①
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);
#案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资
#①查询50号部门的最低工资
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
#②查询每个部门的最低工资
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
#③ 在②基础上筛选,满足min(salary)>①
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);
#非法使用标量子查询
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT salary
FROM employees
WHERE department_id = 250
);
2. Column sub-query (multi-line sub-query)★
Multi-line comparison operator | meaning |
IN/NOT IN | Equal to any one in the list |
ANY/SOME | Compare with a value returned by the subquery |
ALL | Compare with all the values returned by the subquery |
Experience the difference between ANY and ALL, the maximum value MAX and the minimum value MIN.
#案例1:返回location_id是1400或1700的部门中的所有员工姓名
#①查询location_id是1400或1700的部门编号-查询结果是单例多行
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
#②查询员工姓名,要求部门号是①列表中的某一个
SELECT last_name
FROM employees
WHERE department_id IN(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
#或
SELECT last_name
FROM employees
WHERE department_id = ANY(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
#NOT IN 等价于 <> ALL
SELECT last_name
FROM employees
WHERE department_id <> ALL(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
#案例2:返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary
#①查询job_id为‘IT_PROG’部门任一工资
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
#②查询员工号、姓名、job_id 以及salary,salary<(①)的任意一个
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary < ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id <> 'IT_PROG';#区分其他工种
#或
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary < (
SELECT MAX(salary)
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id <> 'IT_PROG';
#案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary < ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#或
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary < (
SELECT MIN(salary)
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
3. Row subquery (result set with one row and multiple columns or multiple rows and multiple columns)-less used
#案例:查询员工编号最小并且工资最高的员工信息-具备两个限制条件的员工不一定存在
#用行子查询,前提是两个条件都是等于,大于
SELECT *
FROM employees
WHERE (employee_id,salary)=(
SELECT MIN(employee_id),MAX(salary)
FROM employees
);
#以前的方法
#①查询最小的员工编号
SELECT MIN(employee_id)
FROM employees
#②查询最高工资
SELECT MAX(salary)
FROM employees
#③查询员工信息
SELECT *
FROM employees
WHERE employee_id=(
SELECT MIN(employee_id)
FROM employees
)AND salary=(
SELECT MAX(salary)
FROM employees
);
Second, select behind
Note: only supports scalar sub-query (one row and one column)
#案例:查询每个部门的员工个数--想要在原来表的基础上加一列“个数”
SELECT d.*,(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.`department_id`
) 个数
FROM departments d;
#案例2:查询员工号=102的部门名-也可以用其他方式代替,因此这个功能弱化了
SELECT (
SELECT department_name #,e.department_id
FROM departments d
INNER JOIN employees e
ON d.department_id=e.department_id
WHERE e.employee_id=102
) 部门名;
Three, behind from
Description: The result of the subquery is used as a table, and an alias must be required
#案例:查询每个部门的平均工资的工资等级
#①查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
SELECT * FROM job_grades;
#②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal
SELECT ag_dep.*,g.`grade_level`
FROM (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
Four, behind exists (correlated subquery)-generally can be replaced by IN
Syntax: exists (complete query statement)-to determine whether there is a value
Result: 1 or 0
SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000); #0
#案例1:查询有员工的部门名
#in
SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
SELECT department_id
FROM employees
)
#exists-先执行外查询,然后用内查询去过滤数据
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.`department_id`=e.`department_id`
);
#案例2:查询没有女朋友的男神信息
#in
SELECT bo.*
FROM boys bo
WHERE bo.id NOT IN(
SELECT boyfriend_id
FROM beauty
)
#exists
SELECT bo.*
FROM boys bo
WHERE NOT EXISTS(
SELECT boyfriend_id
FROM beauty b
WHERE bo.`id`=b.`boyfriend_id`
);
【Case Explanation】Subqueries
No answer version, you can write the code yourself first:
1. Query the name and salary of employees in the same department as Zlotkey
2. Query the employee number, name and salary of employees whose salary is higher than the company's average salary.
3. Query the employee number, name and salary of employees in each department whose salary is higher than the average salary of the department
4. Query the employee number and name of the employee whose name contains the letter u in the same department
5. Query the employee number of employees working in the department whose location_id is 1700
6. Query the name and salary of the employee whose manager is King
7. Query the name of the employee with the highest salary, requiring first_name and last_name to be displayed as a column, and the column name is surname.name
#1. 查询和Zlotkey相同部门的员工姓名和工资
#①查询Zlotkey的部门
SELECT department_id
FROM employees
WHERE last_name = 'Zlotkey'
#②查询部门号=①的姓名和工资
SELECT last_name,salary
FROM employees
WHERE department_id = (
SELECT department_id
FROM employees
WHERE last_name = 'Zlotkey'
)
#2.查询工资比公司平均工资高的员工的员工号,姓名和工资。
#①查询平均工资
SELECT AVG(salary)
FROM employees
#②查询工资>①的员工号,姓名和工资。
SELECT last_name,employee_id,salary
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
);
#3.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资
#①查询各部门的平均工资--新表
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
#②连接①结果集和employees表,进行筛选
SELECT employee_id,last_name,salary,e.department_id
FROM employees e
INNER JOIN (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
ON e.department_id = ag_dep.department_id
WHERE salary > ag_dep.ag ;
#4. 查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
#①查询姓名中包含字母u的员工的部门
SELECT DISTINCT department_id
FROM employees
WHERE last_name LIKE '%u%'
#②查询部门号=①中的任意一个的员工号和姓名
SELECT last_name,employee_id
FROM employees
WHERE department_id IN(
SELECT DISTINCT department_id
FROM employees
WHERE last_name LIKE '%u%'
);
#5. 查询在部门的location_id为1700的部门工作的员工的员工号
#①查询location_id为1700的部门
SELECT DISTINCT department_id
FROM departments
WHERE location_id = 1700
#②查询部门号=①中的任意一个的员工号
SELECT employee_id
FROM employees
WHERE department_id =ANY(
SELECT DISTINCT department_id
FROM departments
WHERE location_id = 1700
);
#6.查询管理者是King的员工姓名和工资
#①查询姓名为king的员工编号
SELECT employee_id
FROM employees
WHERE last_name = 'K_ing'
#②查询哪个员工的manager_id = ①
SELECT last_name,salary
FROM employees
WHERE manager_id IN(
SELECT employee_id
FROM employees
WHERE last_name = 'K_ing'
);
#7.查询工资最高的员工的姓名,要求first_name和last_name显示为一列,列名为 姓.名
#①查询最高工资
SELECT MAX(salary)
FROM employees
#②查询工资=①的姓.名
SELECT CONCAT(first_name,last_name) "姓.名"
FROM employees
WHERE salary=(
SELECT MAX(salary)
FROM employees
);
Advanced 8: Pagination Query★
Application scenarios:
When the data to be displayed is not fully displayed on one page, you need to submit the sql request in pages
grammar:
select 查询列表
from 表
【join type join 表2
on 连接条件
where 筛选条件
group by 分组字段
having 分组后的筛选
order by 排序的字段】
limit 【offset,】size;
among them:
offset-the starting index of the item to be displayed (starting index starts from 0)
size-the number of entries to be displayed
Features:
①The limit statement is placed at the end of the query statement
②Formula: The number of pages to be displayed is known, and the number of entries per page is size, then limit (page-1)*size,size;
Code analysis:
#案例1:查询前五条员工信息
SELECT * FROM employees LIMIT 0,5;
SELECT * FROM employees LIMIT 5;#起始索引为0可以省略
#案例2:查询第11条——第25条
SELECT * FROM employees LIMIT 10,15;
#案例3:有奖金的员工信息,并且工资较高的前10名显示出来
SELECT
*
FROM
employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10 ;
Note: Record the study notes, if you find any mistakes, please correct me! Please contact me for reprinting.