为什么 FIRST_VALUE 和 LAST_VALUE 不是 SQL 中的聚合函数?
Why isn't FIRST_VALUE and LAST_VALUE an aggregation function in SQL?
SQL只将FIRST_VALUE和LAST_VALUE实现为窗口函数而不是聚合函数,有什么特殊原因吗?我发现遇到 "find the item with highest price in each category" 之类的问题很常见。而其他语言(例如 python)提供 MIN/MAX 带有关键字的函数,例如
MAX(item_name, key=lambda x: revenue[x])
是可能的,在 SQL 中解决这个问题的唯一方法似乎是:
WITH temp as(
SELECT *, FIRST_VALUE(item_name) OVER(PARTITION BY category ORDER BY revenue) as fv
FROM catalog)
SELECT category, MAX(fv) -- MIN(fv) also OK
FROM temp
GROUP BY category;
有没有特殊原因FIRST_VALUE中没有"aggregation version"使得
SELECT category, FIRST_VALUE(item_name, revenue)
FROM catalog
GROUP BY
category
还是就是这样?
就我而言,就是这样。我怀疑唯一真正的答案是“因为它不在 SQL 规范中”,并且唯一能够真正回答 为什么 它不在规范中的人是人们谁写的。 “(相关外部机构的名称)在强制要求(产品名称)应该像这样运作时在想什么” 这种形式的问题实际上在这里通常是题外话,因为很少有人能够可靠而真实地回答..我什至不喜欢我自己在这里的回答,因为它感觉像是对一个无法实际回答的问题的扩展评论
聚合函数适用于数据集,虽然其中一些可能需要一些隐含的排序操作,例如中位数,但这些函数始终与它们正在操作的列有关,而不是“给我该列的值”基于该列的顺序”。
有很多 window/analytic 函数没有必然的聚合版本,并且 window 函数的最终用途与聚合不同。您可以想象它们中的一些执行聚合,然后将聚合结果连接回主数据,以便将聚合结果与特定行相关联,但我不会假设这两个工具(agg vs window)完全相关
据我了解 python(不是 python 开发者),它没有进行任何聚合,它正在搜索 item_name 字符串列表并在returns 该项目的收入的字典,并返回具有最大收入的 item_name。那里没有任何分组,它更像是一个 SELECT TOP 1 item_name ORDER BY revenue
并且只对返回单个项目非常有用,而不是一堆在他们的组中都是最大值的项目,除非它在一个循环中使用每次都在处理不同的项目名称列表
我知道您的问题不完全是关于这个特定的 SQL 查询,但如果我在其中提及几件事,它可能对您有所帮助。我不太确定是什么:
WITH temp as(
SELECT *, FIRST_VALUE(item_name) OVER(PARTITION BY category ORDER BY revenue) as fv
FROM catalog
)
SELECT category, MAX(fv) -- MIN(fv) also OK
FROM temp
GROUP BY category;
给你类似的东西:
SELECT DISTINCT category, FIRST_VALUE(item_name) OVER(PARTITION BY category ORDER BY revenue) as fv
FROM catalog
analytic/window 将为每个类别(分区)产生相同的值,因此似乎所有额外的分组依据都在减少重复值——这可以通过获取更简单的答案来回答您想要的值并使用 distinct 来消除重复项(我提倡这样的少数情况之一)
在 "I want the entire most X row as determined by highest/lowest Y" 的更一般意义上,我们通常使用行号:
WITH temp as(
SELECT *, ROW_NUMBER(item_name) OVER(PARTITION BY category ORDER BY revenue) as rn
FROM catalog)
SELECT *
FROM temp
WHERE rn = 1;
虽然我发现它更多 compact/readable 免除 CTE 并且只使用子查询但是 YMMV
SQL只将FIRST_VALUE和LAST_VALUE实现为窗口函数而不是聚合函数,有什么特殊原因吗?我发现遇到 "find the item with highest price in each category" 之类的问题很常见。而其他语言(例如 python)提供 MIN/MAX 带有关键字的函数,例如
MAX(item_name, key=lambda x: revenue[x])
是可能的,在 SQL 中解决这个问题的唯一方法似乎是:
WITH temp as(
SELECT *, FIRST_VALUE(item_name) OVER(PARTITION BY category ORDER BY revenue) as fv
FROM catalog)
SELECT category, MAX(fv) -- MIN(fv) also OK
FROM temp
GROUP BY category;
有没有特殊原因FIRST_VALUE中没有"aggregation version"使得
SELECT category, FIRST_VALUE(item_name, revenue)
FROM catalog
GROUP BY
category
还是就是这样?
就我而言,就是这样。我怀疑唯一真正的答案是“因为它不在 SQL 规范中”,并且唯一能够真正回答 为什么 它不在规范中的人是人们谁写的。 “(相关外部机构的名称)在强制要求(产品名称)应该像这样运作时在想什么” 这种形式的问题实际上在这里通常是题外话,因为很少有人能够可靠而真实地回答..我什至不喜欢我自己在这里的回答,因为它感觉像是对一个无法实际回答的问题的扩展评论
聚合函数适用于数据集,虽然其中一些可能需要一些隐含的排序操作,例如中位数,但这些函数始终与它们正在操作的列有关,而不是“给我该列的值”基于该列的顺序”。
有很多 window/analytic 函数没有必然的聚合版本,并且 window 函数的最终用途与聚合不同。您可以想象它们中的一些执行聚合,然后将聚合结果连接回主数据,以便将聚合结果与特定行相关联,但我不会假设这两个工具(agg vs window)完全相关
据我了解 python(不是 python 开发者),它没有进行任何聚合,它正在搜索 item_name 字符串列表并在returns 该项目的收入的字典,并返回具有最大收入的 item_name。那里没有任何分组,它更像是一个 SELECT TOP 1 item_name ORDER BY revenue
并且只对返回单个项目非常有用,而不是一堆在他们的组中都是最大值的项目,除非它在一个循环中使用每次都在处理不同的项目名称列表
我知道您的问题不完全是关于这个特定的 SQL 查询,但如果我在其中提及几件事,它可能对您有所帮助。我不太确定是什么:
WITH temp as(
SELECT *, FIRST_VALUE(item_name) OVER(PARTITION BY category ORDER BY revenue) as fv
FROM catalog
)
SELECT category, MAX(fv) -- MIN(fv) also OK
FROM temp
GROUP BY category;
给你类似的东西:
SELECT DISTINCT category, FIRST_VALUE(item_name) OVER(PARTITION BY category ORDER BY revenue) as fv
FROM catalog
analytic/window 将为每个类别(分区)产生相同的值,因此似乎所有额外的分组依据都在减少重复值——这可以通过获取更简单的答案来回答您想要的值并使用 distinct 来消除重复项(我提倡这样的少数情况之一)
在 "I want the entire most X row as determined by highest/lowest Y" 的更一般意义上,我们通常使用行号:
WITH temp as(
SELECT *, ROW_NUMBER(item_name) OVER(PARTITION BY category ORDER BY revenue) as rn
FROM catalog)
SELECT *
FROM temp
WHERE rn = 1;
虽然我发现它更多 compact/readable 免除 CTE 并且只使用子查询但是 YMMV