Mysql Professional Series - Part 8: Detailed sorting and paging (order by & limit), and the presence of pits

This is the first series Mysql 8.

Presentation mysql5.7.25, cmd command: the environment.

Tag is [] indicate optional included, | symbol indicates optional separate one.

In this chapter

  1. Detailed ordering inquiry
  2. Detailed limit
  3. Existing pit limit
  4. Paging query pit

Sort query (order by)

Electricity supplier in: we want to see all of today's transaction orders, in accordance with the volume of transactions in descending order, then we can use the sorting function in the database is done.

Sort syntax:

select 字段名 from 表名 order by 字段1 [asc|desc],字段2 [asc|desc];

Sort required fields followed order byafter;

asc | desc sort of presentation rules, asc: ascending, desc: descending, the default is asc;

It supports a plurality of sort fields, separated by commas multiple field sorts.

Single field sorting

mysql> create table test2(a int,b varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test2 values (10,'jack'),(8,'tom'),(5,'ready'),(100,'javacode');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from test2;
+------+----------+
| a    | b        |
+------+----------+
|   10 | jack     |
|    8 | tom      |
|    5 | ready    |
|  100 | javacode |
+------+----------+
4 rows in set (0.00 sec)

mysql> select * from test2 order by a asc;
+------+----------+
| a    | b        |
+------+----------+
|    5 | ready    |
|    8 | tom      |
|   10 | jack     |
|  100 | javacode |
+------+----------+
4 rows in set (0.00 sec)

mysql> select * from test2 order by a desc;
+------+----------+
| a    | b        |
+------+----------+
|  100 | javacode |
|   10 | jack     |
|    8 | tom      |
|    5 | ready    |
+------+----------+
4 rows in set (0.00 sec)

mysql> select * from test2 order by a;
+------+----------+
| a    | b        |
+------+----------+
|    5 | ready    |
|    8 | tom      |
|   10 | jack     |
|  100 | javacode |
+------+----------+
4 rows in set (0.00 sec)

Multi-field sorting

For example, students table, press the age of the students in descending order of age is the same, then the student number in ascending order, as follows:

mysql> create table stu(id int not null comment '学号' primary key,age tinyint not null comment '年龄',name varchar(16) comment '姓名');
Query OK, 0 rows affected (0.01 sec)

mysql> insert into stu (id,age,name) values (1001,18,'路人甲Java'),(1005,20,'刘德华'),(1003,18,'张学友'),(1004,20,'张国荣'),(1010,19,'梁朝伟');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from stu;
+------+-----+---------------+
| id   | age | name          |
+------+-----+---------------+
| 1001 |  18 | 路人甲Java    |
| 1003 |  18 | 张学友        |
| 1004 |  20 | 张国荣        |
| 1005 |  20 | 刘德华        |
| 1010 |  19 | 梁朝伟        |
+------+-----+---------------+
5 rows in set (0.00 sec)

mysql> select * from stu order by age desc,id asc;
+------+-----+---------------+
| id   | age | name          |
+------+-----+---------------+
| 1004 |  20 | 张国荣        |
| 1005 |  20 | 刘德华        |
| 1010 |  19 | 梁朝伟        |
| 1001 |  18 | 路人甲Java    |
| 1003 |  18 | 张学友        |
+------+-----+---------------+
5 rows in set (0.00 sec)

Sort by Alias

mysql> select * from stu;
+------+-----+---------------+
| id   | age | name          |
+------+-----+---------------+
| 1001 |  18 | 路人甲Java    |
| 1003 |  18 | 张学友        |
| 1004 |  20 | 张国荣        |
| 1005 |  20 | 刘德华        |
| 1010 |  19 | 梁朝伟        |
+------+-----+---------------+
5 rows in set (0.00 sec)

mysql> select age '年龄',id as '学号' from stu order by 年龄 asc,学号 desc;
+--------+--------+
| 年龄   | 学号   |
+--------+--------+
|     18 |   1003 |
|     18 |   1001 |
|     19 |   1010 |
|     20 |   1005 |
|     20 |   1004 |
+--------+--------+

Sort by function

Students table (id: ID, birth: date of birth, name: name), as follows:

mysql> drop table if exists student;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE student (
    ->   id int(11) NOT NULL COMMENT '学号',
    ->   birth date NOT NULL COMMENT '出生日期',
    ->   name varchar(16) DEFAULT NULL COMMENT '姓名',
    ->   PRIMARY KEY (id)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into student (id,birth,name) values (1001,'1990-10-10','路人甲Java'),(1005,'1960-03-01','刘德华'),(1003,'1960-08-16','张学友'),(1004,'1968-07-01','张国荣'),(1010,'1962-05-16','梁朝伟');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql>
mysql> SELECT * FROM student;
+------+------------+---------------+
| id   | birth      | name          |
+------+------------+---------------+
| 1001 | 1990-10-10 | 路人甲Java    |
| 1003 | 1960-08-16 | 张学友        |
| 1004 | 1968-07-01 | 张国荣        |
| 1005 | 1960-03-01 | 刘德华        |
| 1010 | 1962-05-16 | 梁朝伟        |
+------+------------+---------------+
5 rows in set (0.00 sec)

Requirements: according to birth year ascending number order, check out the number, date of birth, year of birth, name, 2 worded as follows:

mysql> SELECT id 编号,birth 出生日期,year(birth) 出生年份,name 姓名 from student ORDER BY year(birth) asc,id asc;
+--------+--------------+--------------+---------------+
| 编号   | 出生日期     | 出生年份     | 姓名          |
+--------+--------------+--------------+---------------+
|   1003 | 1960-08-16   |         1960 | 张学友        |
|   1005 | 1960-03-01   |         1960 | 刘德华        |
|   1010 | 1962-05-16   |         1962 | 梁朝伟        |
|   1004 | 1968-07-01   |         1968 | 张国荣        |
|   1001 | 1990-10-10   |         1990 | 路人甲Java    |
+--------+--------------+--------------+---------------+
5 rows in set (0.00 sec)

mysql> SELECT id 编号,birth 出生日期,year(birth) 出生年份,name 姓名 from student ORDER BY 出生年份 asc,id asc;
+--------+--------------+--------------+---------------+
| 编号   | 出生日期     | 出生年份     | 姓名          |
+--------+--------------+--------------+---------------+
|   1003 | 1960-08-16   |         1960 | 张学友        |
|   1005 | 1960-03-01   |         1960 | 刘德华        |
|   1010 | 1962-05-16   |         1962 | 梁朝伟        |
|   1004 | 1968-07-01   |         1968 | 张国荣        |
|   1001 | 1990-10-10   |         1990 | 路人甲Java    |
+--------+--------------+--------------+---------------+
5 rows in set (0.00 sec)

Description:

year Function: Date function belongs, you may obtain a corresponding date year.

The above embodiment uses two kinds of ordering, the first function is used in order by, the second is the use of an alias sorting.

After the sort where

There are orders data are as follows:

mysql> drop table if exists t_order;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create table t_order(
    ->   id int not null auto_increment comment '订单编号',
    ->   price decimal(10,2) not null default 0 comment '订单金额',
    ->   primary key(id)
    -> )comment '订单表';
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_order (price) values (88.95),(100.68),(500),(300),(20.88),(200.5);
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from t_order;
+----+--------+
| id | price  |
+----+--------+
|  1 |  88.95 |
|  2 | 100.68 |
|  3 | 500.00 |
|  4 | 300.00 |
|  5 |  20.88 |
|  6 | 200.50 |
+----+--------+
6 rows in set (0.00 sec)

Demand: Query order amount> = 100, sorted in descending order amount, data display 2, the first column: order number, order amount, as follows:

mysql> select a.id 订单编号,a.price 订单金额 from t_order a where a.price>=100 order by a.price desc;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
|            4 |       300.00 |
|            6 |       200.50 |
|            2 |       100.68 |
+--------------+--------------+
4 rows in set (0.00 sec)

limit introduced

limit for limiting the number of rows returned select queries, and the like commonly used in the paging operation.

grammar:

select 列 from 表 limit [offset,] count;

Description:

offset: indicates the offset, popular speak is the number of lines to skip, offset may be omitted, the default is 0, 0 means skip line; range: [0, + ∞).

count: After taking skip start offset rows, rows count taken; range: [0, + ∞).

And count the offset value limit of expression can not be used.

Below we listed some common examples to deepen understanding.

Get the first n rows

select 列 from 表 limit 0,n;
或者
select 列 from 表 limit n;

Example, acquired before the two recording order, as follows:

mysql> create table t_order(
    ->   id int not null auto_increment comment '订单编号',
    ->   price decimal(10,2) not null default 0 comment '订单金额',
    ->   primary key(id)
    -> )comment '订单表';
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_order (price) values (88.95),(100.68),(500),(300),(20.88),(200.5);
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from t_order;
+----+--------+
| id | price  |
+----+--------+
|  1 |  88.95 |
|  2 | 100.68 |
|  3 | 500.00 |
|  4 | 300.00 |
|  5 |  20.88 |
|  6 | 200.50 |
+----+--------+
6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a limit 2;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            1 |        88.95 |
|            2 |       100.68 |
+--------------+--------------+
2 rows in set (0.00 sec)
    
mysql> select a.id 订单编号,a.price 订单金额 from t_order a limit 0,2;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            1 |        88.95 |
|            2 |       100.68 |
+--------------+--------------+
2 rows in set (0.00 sec)

Get the biggest record

We need to get the largest amount of orders for a record, you can do this: first in accordance with the amount of descending, then take the first record, as follows:

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
|            4 |       300.00 |
|            6 |       200.50 |
|            2 |       100.68 |
|            1 |        88.95 |
|            5 |        20.88 |
+--------------+--------------+
6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc limit 1;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
+--------------+--------------+
1 row in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc limit 0,1;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
+--------------+--------------+
1 row in set (0.00 sec)

Get Rank n to the recording of m

We need to skip the n-1 recording, then take m-n + 1 records, as follows:

select 列 from 表 limit n-1,m-n+1;

Such as: We want to get the highest recorded amount of orders 3-5, we need to skip two, then get three records, as follows:

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
|            4 |       300.00 |
|            6 |       200.50 |
|            2 |       100.68 |
|            1 |        88.95 |
|            5 |        20.88 |
+--------------+--------------+
6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc limit 2,3;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            6 |       200.50 |
|            2 |       100.68 |
|            1 |        88.95 |
+--------------+--------------+
3 rows in set (0.00 sec)

Paging query

The development process, we often use paging, paging generally have two parameters:

page: represents the first few pages, from the beginning, the range [1, + ∞)

pageSize: the number of records per page, a range [1, + ∞)

Such as: page = 2, pageSize = 10, p. 210 retrieves pieces of data.

We use limit for paging, syntax is as follows:

select 列 from 表名 limit (page - 1) * pageSize,pageSize;

Requirements: We follow in descending order amount, per page 2, in order to get all order data, page 1, page 2, page 3 data, as follows:

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
|            4 |       300.00 |
|            6 |       200.50 |
|            2 |       100.68 |
|            1 |        88.95 |
|            5 |        20.88 |
+--------------+--------------+
6 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc limit 0,2;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            3 |       500.00 |
|            4 |       300.00 |
+--------------+--------------+
2 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc limit 2,2;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            6 |       200.50 |
|            2 |       100.68 |
+--------------+--------------+
2 rows in set (0.00 sec)

mysql> select a.id 订单编号,a.price 订单金额 from t_order a order by a.price desc limit 4,2;
+--------------+--------------+
| 订单编号     | 订单金额     |
+--------------+--------------+
|            1 |        88.95 |
|            5 |        20.88 |
+--------------+--------------+
2 rows in set (0.00 sec)

Avoid stepping pit

limit can not use the expression

mysql> select * from t_order where limit 1,4+1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 1,4+1' at line 1
mysql> select * from t_order where limit 1+0;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 1+0' at line 1
mysql>

Conclusion: The limit can only back with clear figures.

The latter two figures can not be negative limit

mysql> select * from t_order where limit -1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit -1' at line 1
mysql> select * from t_order where limit 0,-1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit 0,-1' at line 1
mysql> select * from t_order where limit -1,-1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'limit -1,-1' at line 1

There is sort of paging pit

Prepare the data:

mysql> insert into test1 (b) values (1),(2),(3),(4),(2),(2),(2),(2);
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0

mysql> select * from test1;
+---+---+
| a | b |
+---+---+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
+---+---+
8 rows in set (0.00 sec)
    
mysql> select * from test1 order by b asc;
+---+---+
| a | b |
+---+---+
| 1 | 1 |
| 2 | 2 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
| 3 | 3 |
| 4 | 4 |
+---+---+
8 rows in set (0.00 sec)

Here we follow the ascending b, two data page, to obtain the data.

Sql following order of page 1, page 2, page 3, page 4, page 5 of data, as follows:

mysql> select * from test1 order by b asc limit 0,2;
+---+---+
| a | b |
+---+---+
| 1 | 1 |
| 2 | 2 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 2,2;
+---+---+
| a | b |
+---+---+
| 8 | 2 |
| 6 | 2 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 4,2;
+---+---+
| a | b |
+---+---+
| 6 | 2 |
| 7 | 2 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 6,2;
+---+---+
| a | b |
+---+---+
| 3 | 3 |
| 4 | 4 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc limit 7,2;
+---+---+
| a | b |
+---+---+
| 4 | 4 |
+---+---+
1 row in set (0.00 sec)

There are two questions above:

Question 1: look at the first two sql sql and 3, respectively, and the data of 2 on page 3, resulting in the same data, is not ignorant of the force.

Question 2: the entire table only eight records, how data on page 5 will happen, but ignorant of the force.

Let's analyze the above reasons: primarily the presence of the same value b field, when the same value is present sorting process, no other collation, mysql ignorant force, do not know how to sort up.

Like our school stand, according to the height of the sort, as that sort of time how tall it? The same height chaos row.

Recommendation: present value of the same sort, the need to specify a collation, no ambiguity exists in this collation, such as the above can be coupled with a descending order, as follows:

mysql> select * from test1 order by b asc,a desc;
+---+---+
| a | b |
+---+---+
| 1 | 1 |
| 8 | 2 |
| 7 | 2 |
| 6 | 2 |
| 5 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
+---+---+
8 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 0,2;
+---+---+
| a | b |
+---+---+
| 1 | 1 |
| 8 | 2 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 2,2;
+---+---+
| a | b |
+---+---+
| 7 | 2 |
| 6 | 2 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 4,2;
+---+---+
| a | b |
+---+---+
| 5 | 2 |
| 2 | 2 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 6,2;
+---+---+
| a | b |
+---+---+
| 3 | 3 |
| 4 | 4 |
+---+---+
2 rows in set (0.00 sec)

mysql> select * from test1 order by b asc,a desc limit 8,2;
Empty set (0.00 sec)

See above results, paged data are normal, page 5 nor the data.

to sum up

  • order by ... [asc | desc] used to sort the query results, asc: ascending, desc: descending, asc | desc can be omitted, the default is asc
  • limit for limiting the number of rows of the query results returned, there are two parameters (offset, count), offset: indicates how many rows to skip, count: count represents taking skip line after line offset
  • limit the offset may be omitted, the default value is 0
  • limit the offset and count must be greater than or equal to 0
  • And count the offset value limit of expression can not be used
  • When paging, the sort not ambiguous, may cause paged results out of order under ambiguous circumstances, you can append a primary sort key in the back

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

mysql series of about 20 articles, please look like! I wish you all a happy Mid-Autumn Festival in advance!

Guess you like

Origin www.cnblogs.com/itsoku123/p/11512508.html