从表中检索最后 N 条记录

Posted

技术标签:

【中文标题】从表中检索最后 N 条记录【英文标题】:Retrieve last N records from a table 【发布时间】:2014-12-27 16:37:12 【问题描述】:

我已搜索但未找到我的问题的答案。

我有一个由

组成的订单表 id(主键自动编号) client_id :标识每个客户端(唯一) 日期:每个客户的订单日期

我想在单个视图中检索每个客户的最后 N 个订单日期

当然,我可以使用SELECT TOP N date FROM orders WHERE client = 'xx' ORDER DESC,然后将UNION 用于客户端的不同值。问题在于,随着客户群的变化,该语句将需要修订,而UNION 语句对于庞大的客户群是不切实际的。

作为附加要求,这需要在 Access SQL 中工作。

【问题讨论】:

【参考方案1】:

第 1 步:创建一个查询,为每一行生成一个每个客户按日期排列的顺序。由于 Access SQL 不像 SQL Server 那样具有ROW_NUMBER() OVER (...),因此您可以使用以下问题中描述的技术来模拟这一点:

Access query producing results like ROW_NUMBER() in T-SQL

如果您正确完成了第 1 步,您的结果应该如下:

id   client_id    date      rank
----------------------------------
        1       2014-12-01   7 
        1       2014-12-02   6 
        1       2014-12-05   5 
        1       2014-12-07   4 
        1       2014-12-11   3 
        1       2014-12-14   2 
        1       2014-12-15   1 
        2       2014-12-01   2 
        2       2014-12-02   1
       ... 

第 2 步:将第 1 步的结果用作子查询并过滤结果,以便仅返回带有 rank <= N 的记录。

【讨论】:

【参考方案2】:

我认为以下内容适用于 MS Access:

select t.*
from table as t
where t.date in (select top N t2.date
                 from table as t2
                 where t2.client_id = t.client_id
                 order by t2.date desc
                );

MS Access 的一个问题是,如果存在关联,top N 将检索到多于 N 的记录。如果你想要精确的“N”,那么你可以在子查询中使用order by date, id

【讨论】:

好主意,但我认为您需要在 id 上进行 WHERE 比较,而不是在 date 上。考虑三个客户在2014-12-01 上订购的情况,但其中两个只是“相关”(即在最后五个订单中)。您的查询将返回所有三个记录。 @Heinzi 。 . .我不明白你的评论。我认为 OP 非常清楚“每个客户的最后 N 个订单日期”。当然,如果 OP 在“最后 N 个订单日期”的定义中表示 id 而不是 date,那么她/他当然可以使用该字段。至于客户数量,则由toporder by的交互处理。 啊,我明白了。当然,你是对的:我认为他想要“每个客户的最后 N 个订单日期”,即一个表 client_id, date,每个 client_id 最多有 N 个条目。当然,他给出的 UNION 示例将导致“所有日期都在 any 客户的最后 5 个订单日期内”。您的 SQL 完美地解决了这个问题。我仍然相信他实际上可能想要第一种解释(这会更有意义)。 感谢 Gordon,这正是我所需要的。非常感谢你让我开心,

以上是关于从表中检索最后 N 条记录的主要内容,如果未能解决你的问题,请参考以下文章

sql从表中检索数据并使它们链接

php检索插入的最后一条记录的ID并将其插入另一个表中

如何从表中检索我的最后一个插入行?

从表中检索特定 24 小时时间范围内的记录

从表中检索所有不同的记录,如果两个相似的不同记录之间发生任何更改,则需要同时考虑两者。使用选择查询

Oracle查询优化改写--------------------单表查询