foreword
✨Welcome to Xiao K 's MySQL column , this section will bring you the explanation of MySQL scalar/single row subquery, column/table subquery✨
Table of contents
1. Subquery concept
A subquery refers to a query in which a query statement is nested inside another query statement. This feature has been
MySQL 4.1
introduced from the beginning; in certain cases, the conditions of a query statement need to be obtained by another query statement, and theinner query
query result of the inner query ( ) statement , you canouter query
provide query conditions for the outer query ( ) statement.
The inner query is the subquery, and the outer query is the main query, but they are called differently.
✨Query requirements:
Query the information of the employees with the lowest salary in the company
What is the minimum salary?
SELECT * FROM emp WHERE sal=(SELECT MIN(sal) FROM emp);
✨Subquery specification:
- Subqueries must be enclosed in parentheses
- Subqueries are generally placed on the right side of comparison operators to enhance code readability
- Subqueries can appear in almost any
SELECT
clause (eg:SELECT、FROM、WHERE、ORDER BY、HAVING子句
)
✨ Subquery classification:
-
Classify based on the data returned by the subquery:
-
Scalar subquery (scalar subquery) : returns a value in 1 row and 1 column
-
Row subquery (row subquery) : The returned result set is 1 row and N columns
-
Column subquery (column subquery) : the returned result set is N rows and 1 column
-
Table subquery (table subquery) : the returned result set is N rows and N columns
A subquery can return a scalar (just a value), a row, a column, or a table. These subqueries are called scalar, row, column, and table subqueries, respectively.
-
-
Classification according to whether there is a conditional association between the subquery and the main query:
- Correlated subquery: There is a certain conditional association (relationship) between two queries
- Uncorrelated subquery: There is no conditional association between the two queries (independent of each other)
-
For convenience, here are some personal suggestions for where to use subqueries:
- The subquery appears in the WHERE clause: at this time, the results returned by the subquery are generally single-column single-row, single-row multi-column, multi-row single-column
- The subquery appears in the HAVING clause: at this time, the subquery returns single-row single-column data, and at the same time, in order to use the statistical function operation
- The subquery appears in the FROM clause: at this time, the result map returned by the subquery is generally multi-row and multi-column, and can be operated in the form of a data table (temporary table)
2. Scalar/single row subquery, column/table subquery
✨✨Scalar subqueries
The subquery returns data with a single row and a single column, which is a value
- Query the information of all employees whose basic salary is lower than ALLEN
SELECT * FROM emp WHERE sal<(SELECT sal FROM emp WHERE eanme='ALLEN');
- Query all employee information whose basic salary is higher than the company's average salary
SELECT * FROM emp WHERE sal>(SELECT AVG(sal) FROM emp);
- Query the information of all employees who work in the same job as ALLEN and whose basic salary is higher than employee number 7521
SELECT * FROM emp WHERE job=(SELECT job FROM emp WHERE ename='ALLEN')
AND sal>(SELECT sal FROM emp WHERE empno=7521)
#把ALLEN自己去掉
AND ename<>'ALLEN';
✨The effect is as follows:
✨✨Single row subqueries
The subquery returns data with a single row and multiple columns, which is a record
- Query the information of employees who are engaged in the same job as SCOTT and have the same salary
SELECT * FROM emp WHERE (job,sal)=(SELECT job,sal FROM emp WHERE ename='SCOTT')
AND ename<>'SCOTT';
- Query the information of all employees who are engaged in the same job and have the same leadership as employee number 7566
SELECT * FROM emp WHERE (job,mgr)=(SELECT job,mgr FROM emp WHERE empno=7566)
AND emp<>7566;
✨The effect is as follows:
✨✨Column subquery (multi-row subquery)
A subquery returns multiple rows and a single column of data, that is, one column of data. A multi-row subquery is also known as a set comparison subquery,
When using multi-row subqueries, you need to use multi-row comparison operators:
operator | meaning |
---|---|
IN | is equal to any one in the list |
ANY | Need to be used together with single-row comparison operators (>, <, =, <>...), compare with any value in the subquery result, one is established |
ALL | Need to be used together with single-row comparison operators (>, <, =, <>...), and compare with all values returned by the subquery, and simultaneously hold |
SOME | In fact, it is an alias of ANY, with the same function, generally use ANY |
-
IN operator
The IN operator is used to determine whether the value of the expression is in the given list; if so, the return value is 1, otherwise the return value is 0.
The function of NOT IN is exactly the opposite of that of IN. NOT IN is used to judge whether the value of the expression does not exist in the given list; if not, the return value is 1, otherwise the return value is 0.
- Query the employee information that is the same as the minimum salary in each department
- Group by department and calculate the minimum wage for each department
- Query employee information based on minimum wage
- Query the employee information that is the same as the minimum salary in each department
SELECT * FROM emp WHERE sal IN(SELECT MIN(sal) FROM emp GROUP BY deptno)
AND deptno IS NOT NULL;
-
ANY operator
The ANY keyword is a MySQL operator that returns the Boolean value TRUE if the comparison of ANY in the subquery condition is TRUE .
- Query employee information whose salary is higher than any management salary
- Find out the salary of each management
- Salary per employee vs. salary per management
- Query employee information whose salary is higher than any management salary
SELECT * FROM emp WHERE sal >ANY(
SELECT MIN(sal) FROM emp WHERE job='MANAGER' GROUP BY deptno);
-
ALL operator
The ALL keyword is a MySQL operator that returns the Boolean value TRUE if the comparison result of ALL in the subquery condition is TRUE .
- The case is the same as the ANY operator
✨The effect is as follows:
✨✨Table subqueries
The subquery returns data with multiple rows and columns, which is a table.
The IN, ANY, and ALL operators must be used to compare the results returned by the subquery.
✨Combined training:
- In the emp table, get the same employee information as the entry year and leader of any employee in department 10 (used in the where clause)
- Need to
DATE_FORMAT(hiredate,'%Y')
convert the entry date to year
- Need to
SELECT * FROM emp
WHERE (DATE_FORMAT(hiredate,'%Y'),mgr) IN (SELECT DATE_FORMAT(hiredate,'%Y') hiryear,mgr FROM emp WHERE deptno=10);
- Query the number, name, location, number of people in each department, and average salary of each department (used in the from clause)
- Multi-table joint query learned before——emp, dept
- Union query with subquery
SELECT d.deptno,d.dname,d.loc,COUNT(e.deptno),ROUND(AVG(sal),2) FROM
dept d LEFT JOIN emp e
ON e.deptno=d.deptno
GROUP BY d.deptno,d.dname,d.loc;
SELECT dept.deptno,dept.dname,dept.loc,d.count,d.avgsal FROM dept LEFT JOIN
(SELECT deptno,COUNT(*) count,AVG(sal) avgsal FROM emp GROUP BY deptno) d
ON dept.deptno=d.deptno;
- Query all employees working in the 'SALES' department ID, name, base salary, bonus, position, hire date, maximum and minimum salary of the department. (where and from clauses are used at the same time)
#1
SELECT e.empno,e.ename,e.sal,e.comm,e.job,e.hiredate,minsal,maxsal,e.deptno
FROM emp e JOIN
(SELECT deptno,MIN(sal) minsal,MAX(sal) maxsal FROM emp GROUP BY deptno) td
ON e.deptno=td.deptno AND e.deptno=(SELECT deptno FROM dept WHERE dname='SALES');
#2
SELECT e.empno,e.ename,e.sal,e.comm,e.job,e.hiredate,minsal,maxsal,e.deptno
FROM emp e JOIN
(SELECT deptno,MIN(sal) minsal,MAX(sal) maxsal FROM emp GROUP BY deptno
HAVING deptno=(SELECT deptno FROM dept WHERE dname='SALES')) td
ON e.deptno=td.deptno;
- Query the number, name, basic salary, department name, leader name, and department number of all employees whose salary is higher than that of 'ALLEN' or 'CLACRK'.
#隐式方式
SELECT e.empno,e.ename,e.sal,d.dname,me.ename 领导,temp.count FROM emp e,dept d,emp me,
(SELECT deptno,COUNT(deptno) count FROM emp e GROUP BY deptno) temp
WHERE e.deptno=d.deptno AND e.mgr=me.empno AND temp.deptno=e.deptno
AND e.sal >ANY(SELECT sal FROM emp WHERE ename IN('ALLEN','CLARK'))
AND e.ename NOT IN('ALLEN','CLARK');
#显示方式
SELECT e.empno,e.ename,e.sal,d.dname,me.ename 领导,temp.count
FROM emp e
JOIN dept d ON e.deptno=d.deptno
LEFT JOIN emp me ON e.mgr=me.empno
JOIN (SELECT deptno,COUNT(deptno) count FROM emp e GROUP BY deptno) temp ON temp.deptno=e.deptno
AND e.sal >ANY(SELECT sal FROM emp WHERE ename IN('ALLEN','CLARK'))
AND e.ename NOT IN('ALLEN','CLARK');
- List the name, salary, department name, number of people in the department, and average salary of the managers of each department of the company (assuming that each department has only one manager, and the job is 'MANAGER').
#隐式方式
SELECT e.ename,e.sal,d.dname,temp.count,temp.avgsal
FROM emp e,dept d,(SELECT deptno, COUNT(deptno) count,AVG(sal) avgsal FROM emp GROUP BY deptno) temp
WHERE job='MANAGER' AND e.deptno=d.deptno AND temp.deptno=e.deptno;
#显示方式
SELECT e.ename,e.sal,d.dname,temp.count,temp.avgsal
FROM emp e
JOIN dept d ON e.deptno=d.deptno
JOIN (SELECT deptno, COUNT(deptno) count,AVG(sal) avgsal FROM emp GROUP BY deptno) temp ON temp.deptno=e.deptno
AND job='MANAGER';
- Query all employees whose salary is higher than the company's average salary number, name, basic salary, position, employment date, department name, department location, superior leader's name, salary level, number of departments, average salary, and average length of service.
#隐式方式
SELECT e.empno,e.ename,e.sal,e.job,e.hiredate,d.dname,d.loc,me.ename 领导,s.grade,temp.count,temp.avgsal,temp.avgyear
FROM emp e,dept d,emp me,salgrade s,(SELECT deptno,COUNT(deptno) count,AVG(sal) avgsal,AVG(TIMESTAMPDIFF(MONTH,hiredate,CURDATE())/12) avgyear FROM emp GROUP BY deptno) temp
WHERE e.deptno=d.deptno AND e.sal>(SELECT AVG(sal) FROM emp)
AND e.mgr=me.empno
AND e.sal BETWEEN s.losal AND s.hisal
AND temp.deptno=e.deptno;
#显示方式
SELECT e.empno,e.ename,e.sal,e.job,e.hiredate,d.dname,d.loc,me.ename 领导,s.grade,temp.count,temp.avgsal,temp.avgyear
FROM emp e
JOIN dept d ON e.deptno=d.deptno AND e.sal>(SELECT AVG(sal) FROM emp)
LEFT JOIN emp me ON e.mgr=me.empno
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
JOIN (SELECT deptno,COUNT(deptno) count,AVG(sal) avgsal,AVG(TIMESTAMPDIFF(MONTH,hiredate,CURDATE())/12) avgyear FROM emp GROUP BY deptno) temp ON temp.deptno=e.deptno;
3. Summary
- ✨✨Subqueries allow structured queries so that each part of a query statement can be separated.
- ✨✨Subqueries provide another way to perform operations that require complex joins and unions.
- ✨✨ Subqueries are considered more readable by many people. In fact, this is where subqueries come in.