获取每组的最大值
Posted
技术标签:
【中文标题】获取每组的最大值【英文标题】:get max values per group 【发布时间】:2013-01-10 15:16:59 【问题描述】:create view "data" as select [...]
语句产生的原始数据:
projectId resourceId num
1052785922 318153743 10
1052785922 318153743 20
1052785922 318153743 30
1052785936 -2097765361 20
1052785936 318153743 10
1052785936 528513104 30
1052786014 -2097765361 20
1052786014 318153743 10
1052786014 528513104 30
1052786021 -2097765361 20
1052786021 318153743 10
1052786021 528513104 30
1052786099 -2097765361 20
1052786099 318153743 10
我尝试过滤以上数据以仅获取每个 projectId 具有 max(num) 的那些行。
估计结果:
projectId resourceId num
1052785922 318153743 30
1052785936 528513104 30
1052786014 528513104 30
1052786021 528513104 30
1052786099 -2097765361 20
我知道在 num = max(num)
上进行自我左连接的可能性,max(num) over ( partition by projectId )
或 CTE 之类的窗口函数,但我想知道是否还有其他可能性只选择那些具有最高值的 num。
背景: 以上数据只是大图的一个点,比较复杂。由于它是一种观点,因此我不会以这种方式考虑 CTE 或任何东西。视图中提供的数据是为计划应用程序提供数据,运行时非常重要。我不想挣扎,以性能昂贵的视图选择结束。
上面的“原始数据”是一个视图结合了几十个表的数据的结果。我正在寻找一种方法来一次性过滤此视图的创建语句中的分组最大值,而无需在其间放置额外的层或视图!
【问题讨论】:
如果“原始数据”是一个视图而不是一个基表,我认为没有人可以提供关于性能的最佳答案。如果没有实际的查询/视图、表的定义和索引,这只是猜测。 【参考方案1】:像这样:
WITH CTE
AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY projectId ORDER BY num DESC) rownum
FROM Table1
)
SELECT projectId, resourceId, num
FROM CTE
WHERE rownum = 1;
SQL Fiddle Demo
这会给你:
| PROJECTID | RESOURCEID | NUM |
----------------------------------
| 1052785922 | 318153743 | 30 |
| 1052785936 | 528513104 | 30 |
| 1052786014 | 528513104 | 30 |
| 1052786021 | 528513104 | 30 |
| 1052786099 | -2097765361 | 20 |
【讨论】:
正如 OP 中提到的,我当然知道使用 CTE 可以做到这一点。但我在过去认识到运行时问题,处理 CTE、大量数据和一堆引用视图,因为 this 之类的东西。无论如何,我会试一试.. 也许,我错过了确切的定义。 OP中的上述“原始数据”是一个视图组合了几十个表的数据的结果。我正在寻找一种方法来直接一次性过滤此视图的创建语句中的分组最大值,而无需在其间放置额外的层或视图。 @Nico 当您在同一个查询中组合这些数据时,您可以直接执行此操作,将tablename
替换为表引用(连接表、子查询等),然后执行 rownumber() 函数。还尝试显示您拥有的确切查询或表结构。【参考方案2】:
这个巨型脚本不使用排序;)试试
SELECT *
FROM dbo.test3 t
WHERE EXISTS (
SELECT 1
FROM dbo.test3
WHERE projectId = t.projectId
GROUP BY projectId
HAVING MAX(num) = t.num
)
SQLFiddle上的演示
【讨论】:
谢谢你,但我怀疑它会起作用 - 我没有表(在你的例子中 test3 )可用于子选择,因为 OP 中的“原始数据”是视图的结果集!请参阅已编辑的 OP!可能,我没有说得那么清楚!【参考方案3】:我已经将视图创建为从UDF
中选择,以按照 Mahmoud 应该做的方式预处理数据。 UDF
允许我使用临时表而不是 CTE
最终可以多次执行。
感谢大家的提示!
【讨论】:
以上是关于获取每组的最大值的主要内容,如果未能解决你的问题,请参考以下文章