为什么以下两个查询返回相同的结果?
SELECT FIRST(score) FROM (SELECT score FROM scores ORDER BY score ASC)
SELECT FIRST(score) FROM (SELECT score FROM scores ORDER BY score DESC)
考虑到我手动指定子查询的顺序,这很令人困惑。
除非在子查询中使用TOP,否则子查询中的结果顺序无关紧要。大多数SQL变体都不允许这种语法 - 例如,在子查询中使用ORDER BY会在SQL Server中引发错误。
您的顶级查询没有ORDER BY,因此FIRST或TOP 1的概念在该查询的上下文中是未定义的。
在reference docs中,微软表示(强调我的):
由于记录通常不按特定顺序返回(除非查询包含ORDER BY子句),因此这些函数返回的记录将是任意的。
直接回答这个问题:
Access忽略大多数子查询中的ORDER BY
子句。我相信(但无法证明)这是由于查询优化器中的错误/限制,尽管它没有记录在任何地方(我能找到)。我已经使用Access 2007和Access 2016测试了大量SQL来得出这个结论。
要使示例按预期工作:
将TOP 100 PERCENT
添加到子查询中:
SELECT FIRST(score) FROM (SELECT TOP 100 PERCENT score FROM scores ORDER BY score ASC)
SELECT FIRST(score) FROM (SELECT TOP 100 PERCENT score FROM scores ORDER BY score DESC)
何时使用First
/ Last
而不是Max
/ Min
:
当你想要使用这种方法而不是更简单的Min
和Max
聚合函数时,一个很好的例子就是当你需要来自同一记录的另一个字段时,例如,如果底层的scores
表也持有玩家的name
s和round
s游戏中,你可以得到每个name
中最好和最差玩家的score
和round
,如下所示:
SELECT
round, FIRST(name) AS best, FIRST(score) AS highscore, LAST(name) AS worst, LAST(score) AS lowscore
FROM
(SELECT TOP 100 PERCENT * FROM scores ORDER BY score DESC)
GROUP BY
round
你的陈述是一个完美的功能等价物
SELECT Min(Score) FROM Scores
和
SELECT Max(Score) FROM Scores
。
如果您确实想要检索第一个和最后一个分数,则需要一个AutoNumber或DateTime字段来指示输入顺序。然后你可以查询:
SELECT First(Score), Last(Score) FROM Scores ORDER BY MySortKey
如果你坚持你的问题,那么正确的语法就是
SELECT FIRST(score) FROM (SELECT score FROM scores) ORDER BY score ASC
,
或者,简化,
SELECT FIRST(score) FROM scores ORDER BY score ASC