day03 MySQL connection query (sql99 syntax) & sub query & paging query

"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)

grammar:

classification:

Code analysis:

Advanced 7: Subquery

meaning:

classification:

Code analysis:

Advanced 8: Pagination Query★

Application scenarios:

grammar:

Features:

Code analysis:

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.

Guess you like

Origin blog.csdn.net/csdn_xmj/article/details/114192549