sky*_*ork 5 sql sqlite group-by sql-order-by greatest-n-per-group
我有一个带有复合主键(ID,Date)的表,如下所示.
+------+------------+-------+ | ID | Date | Value | +------+------------+-------+ | 1 | 1433419200 | 15 | | 1 | 1433332800 | 23 | | 1 | 1433246400 | 41 | | 1 | 1433160000 | 55 | | 1 | 1432900800 | 24 | | 2 | 1433419200 | 52 | | 2 | 1433332800 | 23 | | 2 | 1433246400 | 39 | | 2 | 1433160000 | 22 | | 3 | 1433419200 | 11 | | 3 | 1433246400 | 58 | | ... | ... | ... | +------+------------+-------+
Date列上还有一个单独的索引.桌子大小适中,目前行约600k,每天增长约2k.
我想做一个SELECT查询,返回Date每个记录的最新3条记录(按时间戳排序)ID.对于每个给定ID的Date值,值始终是唯一的,因此无需担心Date这里的关系.
我尝试了一种自我加入的方法,受到这个答案的启发,但它花了几秒钟才运行并且什么也没有返回:
SELECT p1.ID, p1.Date, p1.Value FROM MyTable AS p1
LEFT JOIN MyTable AS p2
ON p1.ID=p2.ID AND p1.Date<=p2.Date
GROUP BY p1.ID
HAVING COUNT(*)<=5
ORDER BY p1.ID, p1.Date DESC;
Run Code Online (Sandbox Code Playgroud)
什么是快速解决方案?
CL.*_*CL. 11
您可以查找每个ID的最近三个日期:
SELECT ID, Date, Value
FROM MyTable
WHERE Date IN (SELECT Date
FROM MyTable AS T2
WHERE T2.ID = MyTable.ID
ORDER BY Date DESC
LIMIT 3)
Run Code Online (Sandbox Code Playgroud)
或者,查找每个ID的第三个最近日期,并将其用作限制:
SELECT ID, Date, Value
FROM MyTable
WHERE Date >= IFNULL((SELECT Date
FROM MyTable AS T2
WHERE T2.ID = MyTable.ID
ORDER BY Date DESC
LIMIT 1 OFFSET 2),
0)
Run Code Online (Sandbox Code Playgroud)
两个查询都应该从主键的索引中获得良好的性能.
| 归档时间: |
|
| 查看次数: |
14680 次 |
| 最近记录: |