MySQL study notes ------ subquery


#Advanced 7: Subquery
/*
Meaning:
The select statement that appears in other statements is called subquery or inner
query, and the outer query statement is called main query or outer query

Classification:
according to where the subquery appears:
    After select:
        only support scalar subquery
    
    after from:
        support table subquery
    where or after having:
        Scalar subquery (single row) √Column
        subquery (multiple rows) √Row
        
        subquery
        
    behind exists ( Correlation subquery)
        table subquery
depends on the number of rows and columns of the result set:
    scalar subquery (result set has only one row and one column)
    column subquery (result set has only one column and multiple rows)
    row subquery (result set has one row and multiple columns)
    table subquery ( The result set is generally multi-row and multi-column)

*/


#1. After where or having
/*
1. Scalar subquery (single row subquery)
2. Column subquery (multiple row subquery)

3. Row subquery (multiple columns and multiple rows)

Features:
① Subqueries are placed in parentheses
② Subqueries are generally placed on the right side of the condition
③ Scalar subqueries are generally used with single-row operators
> < >= <= = <>

Column subquery, 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 subquery

#Case 1: Who has a higher salary than Abel?

#①Query Abel's salary
SELECT salary
FROM employees
WHERE last_name = 'Abel'

#②Query employee information, satisfy salary>①Result
SELECT *
FROM employees
WHERE salary>(

    SELECT salary
    FROM employees
    WHERE last_name = 'Abel'

);

#Case 2: Return the name, job_id and salary of the employee whose job_id is the same as that of employee No. 141 and whose salary is more than that of employee No. 143

#①Query the job_id of employee No. 141
SELECT job_id
FROM employees
WHERE employee_id = 141

#②Query the salary of employee No. 143
SELECT salary
FROM employees
WHERE employee_id = 143

#③Query the employee's name, job_id and salary, requiring job_id=① and 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

);


#Case 3: Return the last_name, job_id and salary of the employee with the lowest salary in the company

#①Query the company's minimum wage
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
);


#Case 4: Query the department id and its minimum salary whose minimum salary is greater than the minimum salary of department No. 50

#①Query the minimum salary of department 50
SELECT MIN(salary)
FROM employees
WHERE department_id = 50

#②Query the minimum wage of each department

SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id

#③ Screen on the basis of ②, satisfy 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


);

#Illegal use of scalar subquery ----- that is, the subquery result must be one row and one column

SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
    SELECT  salary
    FROM employees
    WHERE department_id = 250


);

#2. Column subquery (multi-row subquery) ★
#Case 1: Return the names of all employees in the department whose location_id is 1400 or 1700

#①Query the department number whose location_id is 1400 or 1700
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)

#②Query the name of the employee, and the department number is required to be one of the list in ①

SELECT last_name
FROM employees
WHERE department_id  <>ALL(
    SELECT DISTINCT department_id
    FROM departments
    WHERE location_id IN(1400,1700)


);


#Case 2: Return the employee number, name, job_id and salary of employees whose salary is lower than any of the jobs whose job_id is 'IT_PROG' in other types of work

#①Query job_id for any salary in the 'IT_PROG' department

SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'

#②Query employee number, name, job_id and salary, any one of 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';


#Case 3: Return the employee number, name, job_id and salary of employees in other departments whose salary is lower than that of the department whose job_id is 'IT_PROG'

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

#or

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)

#Case: Query the employee information with the smallest employee number and the highest salary


#行子查询
SELECT * 
FROM employees
WHERE (employee_id,salary)=(
    SELECT MIN(employee_id),MAX(salary)
    FROM employees
);

#Common Solution
#①Query the smallest employee number
SELECT MIN(employee_id)
FROM employees


#②Query the maximum salary
SELECT MAX(salary)
FROM employees


#③Query employee information
SELECT *
FROM employees
WHERE employee_id=(
    SELECT MIN(employee_id)
    FROM employees


)AND salary=(
    SELECT MAX(salary)
    FROM employees

);


#2. After select
/*
only supports scalar subquery ----- that is, the subquery result can only be one row and one column
*/

#Case: Query the number of employees in each department

SELECT d.*,(

    SELECT COUNT(*)
    FROM employees e
    WHERE e.department_id = d.`department_id`
 ) number
 FROM departments d;
 
 
 #Case 2: Query department name with employee number=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
    
) department name;

#3. After from
/*
The subquery result is used as a table, and an alias is required
*/

#Case: Query the salary level of the average salary of each department
#①Query the average salary of each department
SELECT AVG(salary), department_id
FROM employees
GROUP BY department_id;


SELECT * FROM job_grades;


#②Connect the result set of ① with the job_grades table, filter the average salary 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;

#4, behind exists (correlated subquery)

/*
Syntax:
exists (complete query statement)
Result:
1 or 0

*/

#Is it mainly used for the result of the sub-statement?
SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000);


#Case 1: Query the department name with employees
#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`
);


#Case 2: Query the information of male gods without girlfriends

#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`

);


#---------subquery related cases -----------#

#1. Query the name and salary of employees in the same department as Zlotkey

#(1) Query the same department id as Zlotkey
SELECT department_id
FROM employees
WHERE last_name = 'Zlotkey';

#(2) Query employee name and salary
SELECT `last_name`,`salary`
FROM employees
WHERE department_id=(
    SELECT department_id
    FROM employees
    WHERE last_name = 'Zlotkey'
);


#2. Query the employee number, name and salary of employees whose salary is higher than the company's average salary.

#(1) Query the company's average salary
SELECT AVG(salary)
FROM employees;

#(2) Query the employee number, name and salary of employees whose salary is higher than the company's average salary
SELECT `employee_id`,`last_name`,`salary`
FROM employees
WHERE `salary`>(
    SELECT AVG(salary)
    FROM employees
);


#3. Query the employee number, name and salary of employees whose salary in each department is higher than the average salary of the department

#(1) Query the average salary of each department
SELECT AVG(salary), `department_id`
FROM `employees`
GROUP BY `department_id`;

#(2) Query the employee number, name and salary of employees whose salary is higher than the average salary of the department in each department
SELECT e.`employee_id`,e.`last_name`,e.`salary`
FROM `employees` e
JOIN (
    SELECT AVG(salary) ag,`department_id`
    FROM `employees`
    GROUP BY `department_id`
) n
ON e.`department_id`=n.`department_id`
WHERE e.`salary`>n.ag;


#4. Query and the employee number and name of the employee whose name contains the letter u in the same department

#(1) Query the department id of the employee whose name contains the letter u
SELECT DISTINCT `department_id`
FROM `employees`
WHERE last_name LIKE '%u%';

#(2) Query the employee number and name of employees in the same department as (1)
SELECT `employee_id`,`last_name`
FROM `employees`
WHERE `department_id` IN (
    SELECT DISTINCT `department_id`
    FROM `employees`
    WHERE last_name LIKE '% u%'
);


#5. Query the employee number of the employee who works in the department whose location_id is 1700

#(1) Query the department id whose location_id is 1700
SELECT `department_id`
FROM `departments`
WHERE `location_id`=1700;

#(2) Query the employee number of the employee who works in the department whose location_id is 1700
SELECT `employee_id`
FROM `employees`
WHERE `department_id` IN (
    SELECT `department_id`
    FROM `departments`
    WHERE `location_id`=1700
);


#6. Query the name and salary of the employee whose manager is K_ing

#(1)查询K_ing的id
SELECT `employee_id`
FROM `employees`
WHERE `last_name`='K_ing';

#(2) Query the name and salary of the employee whose manager is K_ing
SELECT m.`last_name`,m.`salary`
FROM `employees` m
WHERE m.`manager_id` IN (
    SELECT `employee_id`
    FROM `employees`
    WHERE `last_name `='K_ing'
);


#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

#①Query the maximum salary
SELECT MAX(salary)
FROM employees

#②Query salary=①surname.name

SELECT CONCAT(first_name,last_name) "姓.名"
FROM employees
WHERE salary=(
    SELECT MAX(salary)
    FROM employees

);

#------subquery summary------#
1. Meaning
The SELECT statement nested inside other statements is called a subquery or inner query, and the
outer statement can be INSERT, UPDATE, DELETE, SELECT, etc. Generally, SELECT is used as an outer statement.
If it is a SELECT statement, this statement is called an outer query or a main query.

2. Classification
1.
After SELECT according to the occurrence position:
        only support scalar subquery
FROM After:
        table subquery
WHERE or HAVING:
        scalar subquery column subquery
        row subquery EXISTS:         scalar subquery         column subquery
        row         subquery         table subquery




2. According to the row and column of the result set
Scalar subquery (single-row subquery): the result set is one row and one column
Column subquery (multi-row subquery): the result set is multiple rows and one column
Row subquery: the result set is multi-row multi-
column subquery : The result set is multi-row and multi-column


3.
After the example of WHERE or HAVING
1. Scalar subquery
Case: Query the name and salary of the employee with the minimum salary
①Minimum salary
SELECT MIN(salary) FROM employees

②Query the name and salary of the employee, and ask for salary=①
SELECT last_name,salary
FROM employees
WHERE salary=(
    SELECT MIN(salary) FROM employees
);

2. Column query
Case: Query the names of all employees who are leaders
①Query the manager_id of all employees
SELECT manager_id
FROM employees

② query name, employee_id belongs to a list of ①
SELECT last_name
FROM employees
WHERE employee_id IN(
    SELECT manager_id
    FROM employees
);

Guess you like

Origin blog.csdn.net/weixin_47156401/article/details/131927945