某些数据库引擎(例如 Microsoft Access)支持FIRST()聚合函数,我在知道该列在组中只有一个值的情况下使用它。
数据库引擎可能可以对此进行优化,就好像它达到任何值一样,它可以将该值标记为已计算。因此,令人惊讶的是为什么 Oracle 或 SQL Server 等中不支持这一点,更重要的是,SQL 标准也不支持这一点。
实际中,人们用MIN()orMAX()代替,但都要求
下面的数据类型具有自然的排序语义,并且排序对用户来说很重要;
数据库引擎必须将中间值与每行中的值进行比较
所以在很多情况下这并不是最优的。
人们有什么不想允许的具体原因吗SELECT ANY(FIELD) ...?(我可以想到两种变体:ANY()给出结果集中该列不为空的任何值;FIRST()给出结果集中第一行的列值,如果没有行则给出 null)
关于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_disc是0到1while0是第一个结果和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>
参考:
WITHIN GROUP:https://www.slideshare.net/MarkusWinand/modern-sql/105every(类似于any):https ://blog.jooq.org/2014/12/18/a-true-sql-gem-you-didnt-know-yet-the-every-aggregate-功能/| 归档时间: |
|
| 查看次数: |
9299 次 |
| 最近记录: |