通常有一个表格,例如字段是帐户、价值和时间。检索每个帐户的最后一个值的最佳设计模式是什么?不幸的是,分组中的最后一个关键字为您提供了数据库中的最后一条物理记录,而不是任何排序的最后一条记录。这意味着恕我直言,它永远不应该被使用。我使用的两种笨拙的方法是子查询方法或辅助查询来确定最后一条记录,然后加入表以查找值。没有更优雅的方法吗?
8 回答
子查询选项对我来说听起来最好,类似于下面的 psuedo-sql。可能/有必要通过连接对其进行优化,这取决于 SQL 引擎的功能。
select *
from table
where account+time in (select account+max(time)
from table
group by account
order by time)
你能不能:
select account,last(value),max(time)
from table
group by account
我对此进行了测试(授予一个非常小的、几乎微不足道的记录集)并且它产生了正确的结果。
编辑:
经过更多测试后,这也不起作用。我在过去的生活中进行了相当多的访问编程,并且觉得有一种方法可以完成您在 1 个查询中提出的要求,但目前我还是一片空白。对不起。
@Tom 一般而言,执行您建议的“In”查询可能对我来说更容易。通常我会做类似的事情
select T1.account, T1.value
from table T as T1
where T1 = (select max(T2.time) from table T as T2 where T1.account = T2.Account)
经过多年的搜索,我终于在#3 下面的链接中找到了答案。上面的子查询可以工作,但速度很慢——就我的目的而言,速度太慢了。
更流行的答案是三级查询:第一级找到最大值,第二级根据第一级查询获取字段值。然后将结果作为一个表加入到主查询中。快速但复杂且耗时的编码/维护。
此链接有效,运行速度仍然很快,并且代码/维护工作量要少得多。感谢本站的作者。
@shs
是的,选择 last(value) 应该有效,但它没有......我的理解虽然我无法提供权威来源,但 last(value) 给出了访问文件中的最后一个物理记录,它意味着它可能是时间上的第一个,但物理上可能是最后一个。因此,我认为您不应该将 last(value) 用于除非常糟糕的随机行之外的任何内容。
也许下面的 SQL 很笨拙,但在 Access 中似乎可以正常工作。
SELECT
a.account,
a.time,
a.value
FROM
tablename AS a INNER JOIN [
SELECT
account,
Max(time) AS MaxOftime
FROM
tablename
GROUP BY
account
]. AS b
ON
(a.time = b.MaxOftime)
AND (a.account = b.account)
;
我正在尝试使用 Access 2003 查询生成器查找组中的最新日期,并在尝试将 LAST 用于日期字段时遇到了同样的问题。但看起来使用 MAX 可以找到最晚的日期。