【MySQL】· One article to understand the four major subqueries

foreword

✨Welcome to Xiao K 's MySQL column , this section will bring you the explanation of MySQL scalar/single row subquery, column/table subquery✨

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.1introduced from the beginning; in certain cases, the conditions of a query statement need to be obtained by another query statement, and the inner queryquery result of the inner query ( ) statement , you can outer queryprovide 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 SELECTclause (eg: SELECT、FROM、WHERE、ORDER BY、HAVING子句)

Subquery classification:

  1. 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.

  2. 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)
  3. 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:

insert image description here

✨✨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:
insert image description here

✨✨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
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
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:

insert image description here

✨✨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
SELECT * FROM emp
WHERE (DATE_FORMAT(hiredate,'%Y'),mgr) IN (SELECT DATE_FORMAT(hiredate,'%Y') hiryear,mgr FROM emp WHERE deptno=10);

insert image description here

  • 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;

insert image description here

  • 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;

insert image description here

  • 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');

insert image description here

  • 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';

insert image description here

  • 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;

insert image description here

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.

Guess you like

Origin blog.csdn.net/qq_72157449/article/details/131303544
Recommended