Mysql 为计算为真的条件内元素设置限制

Mysql 为计算为真的条件内元素设置限制,mysql,sql,Mysql,Sql,我想选择id为1,2,4的行,并按日期降序为每个id获取最多2行 table: t +--------------+-----------+-----------+ | Id | price | Date | +--------------+-----------+-----------+ | 1 | 30 | 2021-05-09| | 1 | 24 | 2021-04-26| |

我想选择id为1,2,4的行,并按日期降序为每个id获取最多2行

table: t
+--------------+-----------+-----------+
| Id           | price     | Date      |
+--------------+-----------+-----------+
|  1           | 30        | 2021-05-09|
|  1           | 24        | 2021-04-26|
|  1           | 33        | 2021-04-13|
|  2           | 36        | 2021-04-18|
|  3           | 15        | 2021-04-04| 
|  3           | 33        | 2021-05-06|
|  4           | 46        | 2021-02-16|
+--------------+-----------+-----------+
比如:

+--------------+-----------+-----------+
| Id           | price     | Date      |
+--------------+-----------+-----------+
|  1           | 30        | 2021-05-09|
|  1           | 24        | 2021-04-26|
|  2           | 36        | 2021-04-18|
|  4           | 46        | 2021-02-16|
+--------------+-----------+-----------+
这将限制获取的总体结果。

使用
行号()

为了提高性能,您需要在
(id,date)
上建立索引。此外,如果给定id在同一日期有多行,则这可能会返回重复项


是一个dbfiddle。

假设每个id将有数千条记录。如果我没有错,内部子查询将获取所有数千行,比如id“1”,然后为所有这些记录分配行号。(这是否会导致性能问题获取所有记录并按日期仅选择2或3条最新记录?@user2248435获取执行计划并查看。这可能取决于可用的索引。@user2248435。相关子查询(具有正确的索引)可能比
行数()更有效。通常情况下,差异不是特别显著,不过。@GordonLinoff谢谢,第二种方法会很好。是否仍要按日期定义限制?。现在它只会按日期获取每个id的最新一行(一行)。@user2248435。当然可以。我修正了答案,因此它适合你的问题。
Select * from t where Id IN ('1','2','4') limit 2 order by Date desc; 
select id, price, date
from (select t.*,
             row_number() over (partition by id order by date desc) as seqnum
      from t
      where id in (1, 2, 4)
     ) t
where seqnum <= 2;
select t.*
from t
where t.id in (1, 2, 4) and
      t.date >= coalesce( (select t2.date
                           from t t2
                           where t2.id = t.id
                           order by t2.date desc
                           limit 1,1
                           ), t.date
                        );