为什么“第一个”或“任意”聚合函数在数据库引擎中不常用?

Ear*_*ine 10 sql database

某些数据库引擎(例如 Microsoft Access)支持FIRST()聚合函数,我在知道该列在组中只有一个值的情况下使用它。

数据库引擎可能可以对此进行优化,就好像它达到任何值一样,它可以将该值标记为已计算。因此,令人惊讶的是为什么 Oracle 或 SQL Server 等中不支持这一点,更重要的是,SQL 标准也不支持这一点。

实际中,人们用MIN()orMAX()代替,但都要求

  1. 下面的数据类型具有自然的排序语义,并且排序对用户来说很重要;

  2. 数据库引擎必须将中间值与每行中的值进行比较

所以在很多情况下这并不是最优的。

人们有什么不想允许的具体原因吗SELECT ANY(FIELD) ...?(我可以想到两种变体:ANY()给出结果集中该列不为空的任何值;FIRST()给出结果集中第一行的列值,如果没有行则给出 null)

Mar*_*and 4

关于first/last

Microsoft Access SQL 支持的语法在标准 SQL 中没有意义:

SELECT  
       First(LastName) as First,
       Last(LastName) as Last
  FROM Employees
Run Code Online (Sandbox Code Playgroud)

来源

在标准 SQL 中,分组发生在排序之前。通常,组是不排序的。这意味着,未定义哪一行是第一行/最后一行。标准 SQL 通常旨在避免具有不确定性行为的构造(存在例外)。

标准 SQL 提供所谓的有序集函数,这些函数接受within group (order by...)子句以在聚合之前在组中建立顺序:

SELECT
        PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY val)
  FROM ...
Run Code Online (Sandbox Code Playgroud)

参数的范围percentile_disc01while0是第一个结果和1最后一个结果。0.5中位数(这是 的常见用例percentile_disc)。

然而,标准 SQL 不提供first/last作为有序集函数,但percentile_disc带有参数的0is 基本上是第一个,而值1基本上会给出最后的结果。

获取第一个/最后一个值的更常见的 SQL 方法是使用 top-n 查询:

SELECT LastName
  FROM Employees
 ORDER BY ...
 FETCH FIRST 1 ROW ONLY
Run Code Online (Sandbox Code Playgroud)

一次性获取第一个和最后一个值有点尴尬。

除此之外,标准 SQL 还提供窗口函数first_value并从分区last_value中选取这些值而不进行分组。

关于any

标准 SQL 有一个聚合函数any,但用于不同的用例。同样,您(MS Access SQL)建议的任何结果都会给您带来不确定的结果,这不是标准 SQL 所鼓励的。

标准 SQL 函数返回一个布尔值,如果任何条件any为 true,则该值为 true。它最好用在从句中:having

SELECT
       *
  FROM ..
 GROUP BY ...
HAVING ANY(<condition>)
Run Code Online (Sandbox Code Playgroud)

这将删除所有no评估为true 的<condition>

参考: