MySQL获取总共20行,但每个唯一id只有10行

MySQL获取总共20行,但每个唯一id只有10行,mysql,top-n,Mysql,Top N,我这里有个小问题,我会尽力解释的。我想获取最新的最高id,表中每个唯一id最多可以存在10行以上/少于10行 因此,如果我想知道ID1和ID2中最近的10行,我会将限制设置为20 2*10 这就是我当前的查询现在的样子,它将错误地获取第一个id的最近20行,因为该id存在10多行 SELECT positions.id , trackedpersons.name , trackedpersons.id , events.name , events.rout

我这里有个小问题,我会尽力解释的。我想获取最新的最高id,表中每个唯一id最多可以存在10行以上/少于10行

因此,如果我想知道ID1和ID2中最近的10行,我会将限制设置为20 2*10

这就是我当前的查询现在的样子,它将错误地获取第一个id的最近20行,因为该id存在10多行

SELECT positions.id
     , trackedpersons.name
     , trackedpersons.id
     , events.name
     , events.route
     , positions.latitude
     , positions.longitude
     , positions.datetime 
  FROM trackedpersons
     , positions
     , events 
 WHERE trackedpersons.id IN (1,2) 
   AND events.id = 1 
   AND events.id = positions.eventid 
   AND positions.trackedpersonid = trackedpersons.id 
 ORDER 
    BY trackedpersons.id
     , positions.id DESC 
 LIMIT 20;

很好,;这里有一个方法-虽然它不是最有效的

考虑以下几点

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table 
(id INT NOT NULL
,dt INT NOT NULL
,PRIMARY KEY(id,dt)
);

INSERT INTO my_table VALUES
(101,1),
(101,2),
(101,3),
(101,4),
(102,1),
(102,2),
(102,3),
(102,4),
(102,5),
(103,1),
(103,2),
(103,3),
(104,1),
(104,2),
(105,1);

SELECT * FROM my_table;
+-----+----+
| id  | dt |
+-----+----+
| 101 |  1 |
| 101 |  2 |
| 101 |  3 |
| 101 |  4 |
| 102 |  1 |
| 102 |  2 |
| 102 |  3 |
| 102 |  4 |
| 102 |  5 |
| 103 |  1 |
| 103 |  2 |
| 103 |  3 |
| 104 |  1 |
| 104 |  2 |
| 105 |  1 |
+-----+----+
为了发现其组中每一行的位置等级,我们可以这样做

SELECT x.*
     , COUNT(*) rank 
  FROM my_table x 
  JOIN my_table y 
    ON y.id = x.id 
   AND y.dt >= x.dt 
 GROUP 
    BY x.id,x.dt 
 ORDER 
    BY id
     , rank;
+-----+----+------+
| id  | dt | rank |
+-----+----+------+
| 101 |  4 |    1 |
| 101 |  3 |    2 |
| 101 |  2 |    3 |
| 101 |  1 |    4 |
| 102 |  5 |    1 |
| 102 |  4 |    2 |
| 102 |  3 |    3 |
| 102 |  2 |    4 |
| 102 |  1 |    5 |
| 103 |  3 |    1 |
| 103 |  2 |    2 |
| 103 |  1 |    3 |
| 104 |  2 |    1 |
| 104 |  1 |    2 |
| 105 |  1 |    1 |
+-----+----+------+
…可以重写,从而从每个id中获得前3名

SELECT x.*  
  FROM my_table x 
  JOIN my_table y  
    ON y.id = x.id 
   AND y.dt >= x.dt 
 GROUP 
    BY x.id
     , x.dt 
HAVING COUNT(*) <= 3;
+-----+----+
| id  | dt |
+-----+----+
| 101 |  2 |
| 101 |  3 |
| 101 |  4 |
| 102 |  3 |
| 102 |  4 |
| 102 |  5 |
| 103 |  1 |
| 103 |  2 |
| 103 |  3 |
| 104 |  1 |
| 104 |  2 |
| 105 |  1 |
+-----+----+

不要使用隐式逗号连接语法。相反,请始终使用显式连接语法。除此之外,这是一个排在前N位的问题,每一个问题都会在这里被问到和回答day@Strawberry我主要使用隐式连接,有什么区别?甚至我也想知道:MySQL根据连接是隐式的还是显式的,以不同的顺序计算连接。如果它们都是隐式的,这与2*3*6=6*2*3没有关系,但是当与不能隐式表示的外部联接结合时,您将开始得到错误或意外的结果。另外,它更难阅读。@flaschenpost这是一个评论,不是答案。