[MySQL] grouping and sorting: obtain the first N records and generate an automatic number sequence, similar to limit_MySQL after groupby

Source: Internet
Author: User
A colleague's business scenario is to group by cid and author, and then reverse the id to retrieve the first two records. In oracle, row_number () OVER (PARTITIONBYcid, authorORDERBYidDESC) can be used to group data by cid and author.
Preface:
The business scenario of a colleague is to group by cid and author, and then reverse the id to retrieve the first two records.

In oracle, row_number () OVER (partition by cid, author order by id DESC) can be used to indicate the group based on cid and author, and the group is sorted BY id within the group, the value calculated by this function indicates the sequential numbers after sorting in each group (the sequential and unique in the group), and the mysql database does not have such a statistical function, you need to write complex SQL statements for implementation.

1. input test data

USE csdn;
Drop table if exists test;
Create table test (
Id int primary key,
Cid INT,
Author VARCHAR (30)
) ENGINE = INNODB;


Insert into test VALUES
(1, 1, \ 'test1 \'),
(2, 1, \ 'test1 \'),
(3,1, \ 'test2 \'),
(4,1, \ 'test2 \'),
(5, 1, \ 'test2 \'),
(6, 1, \ 'test3 \'),
(7,1, \ 'test3 \'),
(8, 1, \ 'test3 \'),
(9,1, \ 'test3 \'),
(10, 2, \ 'test11 \'),
(11,2, \ 'test11 \'),
(12, 2, \ 'test22 \'),
(13,2, \ 'test22 \'),
(14,2, \ 'test22 \'),
(15,2, \ 'test33 \'),
(16,2, \ 'test33 \'),
(17,2, \ 'test33 \'),
(18,2, \ 'test33 \');
Insert into test valuees (200,200, \ '200test _ nagios \');
2. original low-efficiency subquery implementation methods
SELECT * FROM test
WHERE
N> (
Select count (*)
FROM test B
WHERE a. cid = B. cid AND a. 'author' = B. 'author' AND a. id ) Order by cid, author, id DESC;
If you replace N with a number such as 2, the first two records of each group are queried, as shown below:
Mysql> SELECT * FROM test
-> WHERE
-> 2> (
-> Select count (*)
-> FROM test B
-> WHERE a. cid = B. cid AND a. 'author' = B. 'author' AND a. id ->) Order by cid, author, id DESC;
+ ----- + ------ + ---------------- +
| Id | cid | author |
+ ----- + ------ + ---------------- +
| 2 | 1 | test1 |
| 1 | 1 | test1 |
| 5 | 1 | test2 |
| 4 | 1 | test2 |
| 9 | 1 | test3 |
| 8 | 1 | test3 |
| 11 | 2 | test11 |
| 10 | 2 | test11 |
| 14 | 2 | test22 |
| 13 | 2 | test22 |
| 18 | 2 | test33 |
| 17 | 2 | test33 |
| 200 | 200 | 200test_nagios |
+ ----- + ------ + ---------------- +
13 rows in set (0.00 sec)


Mysql>
3. use dynamic SQL
First, construct the serial number and introduce a @ row for rownumber.
SET @ row = 0; SET @ mid = ''; SELECT cid, author, @ row: = @ row + 1 rownum FROM test order by cid, author LIMIT 10;
The serial number has come out, and an additional @ mid is added for grouping, with the focus on case when @ mid = author THEN @ row: = @ row + 1 ELSE @ row: = 1 END rownum, indicates that the group data is automatically traversed from 1 count.

Now, add an inner JOIN to the table and then limit rownumber to get the target data.
SET @ row = 0;
The execution result is as follows:
Mysql> SET @ row = 0;
Query OK, 0 ROWS affected (0.00 sec)


Mysql> SET @ mid = \'\';
Query OK, 0 ROWS affected (0.00 sec)


Mysql> SELECT a. *, B. rownum FROM test
-> Inner join (
-> SELECT cid, author, id, case when @ mid = author THEN @ row: = @ row + 1 ELSE @ row: = 1 END rownum, @ mid: = author MID
-> FROM test
-> Order by cid, author, id DESC
->) B ON B. author = a. author AND B. cid = a. cid AND B. id = a. id WHERE B. rownum <3;
+ ----- + ------ + ---------------- + -------- +
| Id | cid | author | rownum |
+ ----- + ------ + ---------------- + -------- +
| 2 | 1 | test1 | 1 |
| 1 | 1 | test1 | 2 |
| 5 | 1 | test2 | 1 |
| 4 | 1 | test2 | 2 |
| 9 | 1 | test3 | 1 |
| 8 | 1 | test3 | 2 |
| 11 | 2 | test11 | 1 |
| 10 | 2 | test11 | 2 |
| 14 | 2 | test22 | 1 |
| 13 | 2 | test22 | 2 |
| 18 | 2 | test33 | 1 |
| 17 | 2 | test33 | 2 |
| 200 | 200 | 200test_nagios | 1 |
+ ----- + ------ + ---------------- + -------- +
13 rows in set (0.01 sec)


Mysql>
Reference article address:
Http://blog.csdn.net/mchdba/article/details/22163223

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.