First()函数使用什么顺序?

问题描述 投票:5回答:3

为什么以下两个查询返回相同的结果?

SELECT FIRST(score) FROM (SELECT score FROM scores ORDER BY score ASC)
SELECT FIRST(score) FROM (SELECT score FROM scores ORDER BY score DESC)

考虑到我手动指定子查询的顺序,这很令人困惑。

sql ms-access ms-access-2007
3个回答
2
投票

除非在子查询中使用TOP,否则子查询中的结果顺序无关紧要。大多数SQL变体都不允许这种语法 - 例如,在子查询中使用ORDER BY会在SQL Server中引发错误。

您的顶级查询没有ORDER BY,因此FIRST或TOP 1的概念在该查询的上下文中是未定义的。

reference docs中,微软表示(强调我的):

由于记录通常不按特定顺序返回(除非查询包含ORDER BY子句),因此这些函数返回的记录将是任意的。


2
投票

直接回答这个问题:

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

当你想要使用这种方法而不是更简单的MinMax聚合函数时,一个很好的例子就是当你需要来自同一记录的另一个字段时,例如,如果底层的scores表也持有玩家的names和rounds游戏中,你可以得到每个name中最好和最差玩家的scoreround,如下所示:

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

-2
投票

你的陈述是一个完美的功能等价物 SELECT Min(Score) FROM ScoresSELECT 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

© www.soinside.com 2019 - 2024. All rights reserved.