Mysql Professional Series - Part 12: Detailed subqueries

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_employeeslibrary 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

  1. Scalar subqueries (subquery single separate line)
  2. Column subquery (single multiple-row subqueries)
  3. Row subqueries (line multi-column)

Feature

  1. Subquery placed in parentheses.
  2. Subqueries general conditions on the right side.
  3. Scalar query, typically with the use of single separate operators >, <,> =, <=, =, <>,! =
  4. 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);

  5. 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)

  1. Syntax: exists (complete query).
  2. exists Results: 0 or 1, the results of the query exists for concentration determination results of the subquery has a value.
  3. In general, the use of sub-query exists, can be used in place of the absolute, it exists with less.
  4. 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

  1. This article explains common in sub-queries, please be sure to practice
  2. Note that in, any, some, any usage
  3. When a field value is NULL, not in the query have pit, to pay attention to this
  4. Recommended that you create table, the column does not allow null

Mysql series directory

  1. The first one: mysql Basics
  2. Part 2: Detailed mysql data type (Key)
  3. Part 3: Administrator essential skills (must master)
  4. Part 4: DDL common operations
  5. Part 5: DML operation summary (insert, update, delete)
  6. The first six: select Query Basics
  7. Part 7: Fun select query conditions, avoid mining pit
  8. The first eight: Detailed sorting and paging (order by & limit)
  9. Chapter 9: Detailed grouping queries (group by & having)
  10. The first 10: dozens of commonly used functions Detailed
  11. 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!

Guess you like

Origin www.cnblogs.com/itsoku123/p/11577799.html
Recommended