获取每组的最大值

时间:2013-01-10 15:16:59

标签: sql sql-server sql-server-2008 tsql

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值的那些。 / p>

背景: 以上数据只是大视图的一个点,相对复杂。既然这是一种观点,我不会考虑CTE或其他任何方式。视图中提供的数据用于提供计划应用程序,运行时非常重要。我不想挣扎,以性能昂贵的观看选择结束。

以上“原始数据”是组合来自数十个表的数据的视图的结果。我正在寻找一种方法来直接一次性过滤此视图的creation-statement中的分组最大值,而无需在其间添加额外的图层或视图!

3 个答案:

答案 0 :(得分:3)

像这样:

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 |

答案 1 :(得分:1)

这个超级脚本不使用排序;)尝试

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上的演示

答案 2 :(得分:0)

我已经完成了创建视图,从UDF中选择按照Mahmoud应该做的方式预处理数据。 UDF允许我使用临时表而不是CTE,最终可以执行多次。

感谢所有提示!