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

时间:2014-05-07 12:31:04

标签: mysql top-n

我在这里遇到一些问题,我会尝试解释。我想获取表中每个唯一ID的最新(最高id)最多10行(可以存在多于/少于10行)。

所以如果我有兴趣知道id" 1"的最新10行。和" 2"我会将LIMIT设置为20(2 * 10)。

这是我当前的查询现在看起来的样子(它错误地会获取第一个id的最新20行,因为它存在超过10行的id)。

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;

1 个答案:

答案 0 :(得分:0)

非常好;这是一种方式 - 虽然它不是最有效的......

考虑以下内容......

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