Access 2013 - 查询未返回正确的结果数

时间:2014-01-04 04:43:22

标签: sql ms-access-2013

我正在尝试通过以下查询返回每个PlayedTo的两个最低PlayerID结果。

select
    x1.PlayerID, x1.RoundID, x1.PlayedTo
from P_7to8Calcs as x1
where
    (
    select count(*)
    from P_7to8Calcs as x2
    where x2.PlayerID = x1.PlayerID
    and x2.PlayedTo <= x1.PlayedTo
    ) <3
order by PlayerID, PlayedTo, RoundID;

不幸的是,当其中一个得分最低时,它不会返回结果。数据集和代码的副本位于http://sqlfiddle.com/#!3/4a9fc/13

PlayerID 47只返回了一个结果,因为有两个不同的RoundID被绑定为第二个最低PlayedTo。对于我想要计算的内容,它返回这两个中的哪一个并不重要,因为我只需要知道数字是什么,但是对于报告我理想地需要知道具有最新日期的那个。

查询的另一个小问题是运行所花费的时间。在Access中大约需要2分钟来运行83条记录,但是当数据库完全启动并运行时,它需要在大约1000条记录上运行。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

通过在内部排序中添加DatePlayed来解决这个问题(你想要的是最新日期的那个):

select
    x1.PlayerID, x1.RoundID
    , x1.PlayedTo
from P_7to8Calcs as x1
where
    (
    select count(*)
    from P_7to8Calcs as x2
    where x2.PlayerID = x1.PlayerID
    and (x2.PlayedTo < x1.PlayedTo
         or x2.PlayedTo = x1.PlayedTo
            and x2.DatePlayed >= x1.DatePlayed
         )
    ) <3
order by PlayerID, PlayedTo, RoundID;

对于性能,创建支持连接条件的索引。类似的东西:

create index P_7to8Calcs__PlayerID_RoundID on P_7to8Calcs(PlayerId, PlayedTo);

注意:我使用了你的SQLFiddle,因为我没有这里的Acess。


编辑:如果索引没有足够提高性能,您可能希望使用窗口函数尝试以下查询(这避免了嵌套的子查询)。它适用于您的SQLFiddle,但我不确定Access是否支持它。

select x1.PlayerID, x1.RoundID, x1.PlayedTo
from (
  select PlayerID, RoundID, PlayedTo
  , RANK() OVER (PARTITION BY PlayerId ORDER BY PlayedTo, DatePlayed DESC) AS Rank
  from P_7to8Calcs
  ) as x1
where x1.RANK < 3
order by PlayerID, PlayedTo, RoundID;

有关文档,请参阅OVER clauseRanking Functions