This is the first 12 series Mysql.
Presentation mysql5.7.25, cmd command: the environment.
This section is very important.
Subqueries
Appear in the select statement select statement, called sub-query or within the query.
External select query, called the outer query or the main query.
Sub-query classification
Press the number of rows of the result set divided into four kinds
- Query scalar (one result set only one row)
- Liezi query (result set only over one row)
- Row subquery (result set has one row multi-column)
- Table subqueries (usually the result set rows and columns)
Different location subquery appears in the main query points
behind the SELECT : only supports standard quantum query.
back from : Support table subqueries.
or where rear HAVING : a scalar subquery supported (separate single line), column subquery (single multi-line), the row subquery (multiple rows and columns)
behind exists (ie, the relevant sub-query) : sub-table queries (multi-line, multi-column)
Preparation of test data
Test data are more on my personal blog up.
Browser to open links: http://www.itsoku.com/article/209
mysql executed inside javacode2018_employees库
a script section.
Successfully created javacode2018_employees
library and five tables, as follows:
Table Name | description |
---|---|
departments | Sector Table |
employees | Employee information table |
jobs | Position Information Table |
locations | Location table (table departments will be used) |
job_grades | Salary grade table |
The back of select sub-query
Subqueries located behind select, and only supports standard quantum query .
Example 1
The number of employees in each department inquiry
SELECT
a.*,
(SELECT count(*)
FROM employees b
WHERE b.department_id = a.department_id) AS 员工个数
FROM departments a;
Example 2
Queries employee number = 102 department name
SELECT (SELECT a.department_name
FROM departments a, employees b
WHERE a.department_id = b.department_id
AND b.employee_id = 102) AS 部门名;
Back from the sub-query
The sub-query result set to act as a table, which calls for aliases, not those who can not find the table.
Then the real tables and sub-query results table join query.
Example 1
Queries wage level of the average salary for each department
-- 查询每个部门平均工资
SELECT
department_id,
avg(a.salary)
FROM employees a
GROUP BY a.department_id;
-- 薪资等级表
SELECT *
FROM job_grades;
-- 将上面2个结果连接查询,筛选条件:平均工资 between lowest_sal and highest_sal;
SELECT
t1.department_id,
sa AS '平均工资',
t2.grade_level
FROM (SELECT
department_id,
avg(a.salary) sa
FROM employees a
GROUP BY a.department_id) t1, job_grades t2
WHERE
t1.sa BETWEEN t2.lowest_sal AND t2.highest_sal;
The last run was as follows:
mysql> SELECT
t1.department_id,
sa AS '平均工资',
t2.grade_level
FROM (SELECT
department_id,
avg(a.salary) sa
FROM employees a
GROUP BY a.department_id) t1, job_grades t2
WHERE
t1.sa BETWEEN t2.lowest_sal AND t2.highest_sal;
+---------------+--------------+-------------+
| department_id | 平均工资 | grade_level |
+---------------+--------------+-------------+
| NULL | 7000.000000 | C |
| 10 | 4400.000000 | B |
| 20 | 9500.000000 | C |
| 30 | 4150.000000 | B |
| 40 | 6500.000000 | C |
| 50 | 3475.555556 | B |
| 60 | 5760.000000 | B |
| 70 | 10000.000000 | D |
| 80 | 8955.882353 | C |
| 90 | 19333.333333 | E |
| 100 | 8600.000000 | C |
| 110 | 10150.000000 | D |
+---------------+--------------+-------------+
12 rows in set (0.00 sec)
and where the latter having subqueries
or where the back having, may be used
- Scalar subqueries (subquery single separate line)
- Column subquery (single multiple-row subqueries)
- Row subqueries (line multi-column)
Feature
- Subquery placed in parentheses.
- Subqueries general conditions on the right side.
- Scalar query, typically with the use of single separate operators >, <,> =, <=, =, <>,! =
Column subquery, generally with the use of multi-line operator
in (not in): the list of "arbitrary"
any or some: Comparative subqueries and "a certain value" return, such as a> some (10,20,30), a subquery is greater than any one can, is greater than a minimum value to a subquery, equivalent to a > min (10,20,30).
all: and subqueries "all values" returned comparison, such as a> all (10,20,30), a subquery is greater than all the values, in other words, the maximum value A is larger than the subquery query can be satisfied, equivalents, in a> max (10,20,30);
The implementation of sub-queries take precedence over the main query execution, because the condition of the main query uses the result of the subquery.
mysql is in, any, some, all
in, any, some, all sub-queries are one of the keywords.
in : in the expression commonly used where its role is to query data within a certain range
any and some as : may =,>,> =, <, <=, <> in combination, respectively, equal to, greater than, greater equal, less than, less than or equal, not equal to any of the data.
All : may =,>,> =, <, <=, <> are used in combination, respectively, equal to, greater than, greater equal, less than, less than or equal, which is not equal to all the data therein.
Hereinafter will often use these keywords.
Scalar query
Usually scalar query, example
Queries high wages than Abel's who?
/*①查询abel的工资【改查询是标量子查询】*/
SELECT salary
FROM employees
WHERE last_name = 'Abel';
/*②查询员工信息,满足salary>①的结果*/
SELECT *
FROM employees a
WHERE a.salary > (SELECT salary
FROM employees
WHERE last_name = 'Abel');
Query the plurality of scalar, sample
Job_id returned with the same number of 141 employees, salary employees and more than 143 employees, name, salary and job_id
/*返回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=① and salary>②*/
SELECT
a.last_name 姓名,
a.job_id,
a.salary 工资
FROM employees a
WHERE a.job_id = (SELECT job_id
FROM employees
WHERE employee_id = 141)
AND
a.salary > (SELECT salary
FROM employees
WHERE employee_id = 143);
+ Subqueries packet function, examples
Query No. 50 is greater than the minimum wage sector minimum wage and the minimum wage department id [having]
/*查询最低工资大于50号部门最低工资的部门id和其最低工资【having】*/
/*①查询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(a.salary) minsalary,
department_id
FROM employees a
GROUP BY a.department_id
HAVING min(a.salary) > (SELECT min(salary)
FROM employees
WHERE department_id = 50);
Wrong scalar query example
The above example query statement ③ neutron min (salary) to salary, perform the following effects:
mysql> SELECT
min(a.salary) minsalary,
department_id
FROM employees a
GROUP BY a.department_id
HAVING min(a.salary) > (SELECT salary
FROM employees
WHERE department_id = 500000);
ERROR 1242 (21000): Subquery returns more than 1 row
Error: The results of the sub-query returns more than 100 rows.
Note: The above sub-queries only support up to a row of record .
Column subqueries (subquery result set more than one line)
Liezi query needs with multi-line operators to use: in (not in), any / some, all.
To improve efficiency, it is best to re-look distinct keywords.
Example 1
Location_id return all employee names department in 1400 or 1700
/*返回location_id是1400或1700的部门中的所有员工姓名*/
/*方式1*/
/*①查询location_id是1400或1700的部门编号*/
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN (1400, 1700);
/*②查询员工姓名,要求部门是①列表中的某一个*/
SELECT a.last_name
FROM employees a
WHERE a.department_id IN (SELECT DISTINCT department_id
FROM departments
WHERE location_id IN (1400, 1700));
/*方式2:使用any实现*/
SELECT a.last_name
FROM employees a
WHERE a.department_id = ANY (SELECT DISTINCT department_id
FROM departments
WHERE location_id IN (1400, 1700));
/*拓展,下面与not in等价*/
SELECT a.last_name
FROM employees a
WHERE a.department_id <> ALL (SELECT DISTINCT department_id
FROM departments
WHERE location_id IN (1400, 1700));
Example 2
Other types of return is lower than job_id any jobs' IT_PROG 'employees' wages the employee number, name, job_id, salary
/*返回其他工种中比job_id为'IT_PROG'工种任一工资低的员工的员工号、姓名、job_id、salary*/
/*①查询job_id为'IT_PROG'部门任-工资*/
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG';
/*②查询员工号、姓名、job_id、salary,slary<①的任意一个*/
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';
Example 3
Other types of return is lower than job_id 'IT_PROG' departments of all employees' wages the employee number, name, job_id, salary
/*返回其他工种中比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';
Row subquery (subquery result set row multi-column)
Examples
Queries minimum number of employees and the highest paid employee information, in three ways.
/*查询员工编号最小并且工资最高的员工信息*/
/*①查询最小的员工编号*/
SELECT min(employee_id)
FROM employees;
/*②查询最高工资*/
SELECT max(salary)
FROM employees;
/*③方式1:查询员工信息*/
SELECT *
FROM employees a
WHERE a.employee_id = (SELECT min(employee_id)
FROM employees)
AND salary = (SELECT max(salary)
FROM employees);
/*方式2*/
SELECT *
FROM employees a
WHERE (a.employee_id, a.salary) = (SELECT
min(employee_id),
max(salary)
FROM employees);
/*方式3*/
SELECT *
FROM employees a
WHERE (a.employee_id, a.salary) in (SELECT
min(employee_id),
max(salary)
FROM employees);
Mode 1 is more common, more concise manner 2,3.
Behind exists (also called correlated subqueries)
- Syntax: exists (complete query).
- exists Results: 0 or 1, the results of the query exists for concentration determination results of the subquery has a value.
- In general, the use of sub-query exists, can be used in place of the absolute, it exists with less.
- And in front of the queries are different, this first main query is executed, and then the main query results of the query, the query filter according to the sub, sub-queries related to the main fields used in the query, so called correlated subquery.
Example 1
A simple example
mysql> SELECT exists(SELECT employee_id
FROM employees
WHERE salary = 300000) AS 'exists返回1或者0';
+----------------------+
| exists返回1或者0 |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.00 sec)
Example 2
Query department name for all employees
/*exists入门案例*/
SELECT exists(SELECT employee_id
FROM employees
WHERE salary = 300000) AS 'exists返回1或者0';
/*查询所有员工部门名*/
SELECT department_name
FROM departments a
WHERE exists(SELECT 1
FROM employees b
WHERE a.department_id = b.department_id);
/*使用in实现*/
SELECT department_name
FROM departments a
WHERE a.department_id IN (SELECT department_id
FROM employees);
Example 3
No employees of the department inquiry
/*查询没有员工的部门*/
/*exists实现*/
SELECT *
FROM departments a
WHERE NOT exists(SELECT 1
FROM employees b
WHERE a.department_id = b.department_id AND b.department_id IS NOT NULL);
/*in的方式*/
SELECT *
FROM departments a
WHERE a.department_id NOT IN (SELECT department_id
FROM employees b
WHERE b.department_id IS NOT NULL);
The above script there
b.department_id IS NOT NULL
, why, there are pit, looking down.
NULL pit
Example 1
Use not in the way the sector inquiry no employees, as follows:
SELECT *
FROM departments a
WHERE a.department_id NOT IN (SELECT department_id
FROM employees b);
operation result:
mysql> SELECT *
-> FROM departments a
-> WHERE a.department_id NOT IN (SELECT department_id
-> FROM employees b);
Empty set (0.00 sec)
Not in the case, the value is NULL when the sub-columns in the query, the outer query result is empty.
Recommendation: construction of the table, the column does not allow empty.
to sum up
- This article explains common in sub-queries, please be sure to practice
- Note that in, any, some, any usage
- When a field value is NULL, not in the query have pit, to pay attention to this
- Recommended that you create table, the column does not allow null
Mysql series directory
- The first one: mysql Basics
- Part 2: Detailed mysql data type (Key)
- Part 3: Administrator essential skills (must master)
- Part 4: DDL common operations
- Part 5: DML operation summary (insert, update, delete)
- The first six: select Query Basics
- Part 7: Fun select query conditions, avoid mining pit
- The first eight: Detailed sorting and paging (order by & limit)
- Chapter 9: Detailed grouping queries (group by & having)
- The first 10: dozens of commonly used functions Detailed
- The first 11: in-depth understanding of the principles and join query
mysql series of about 20 articles, please look like, welcome to add me or leave a message exchange micro-channel itsoku mysql related technologies!