1

作为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

我知道 self left join on num = max(num)、window-function likemax(num) over ( partition by projectId )或 CTE 的可能性,但我想知道是否还有其他可能性来选择那些具有最高 num 值的那些。

背景:以上数据只是大图的一个点,比较复杂。由于它是一种观点,因此我不会以这种方式考虑 CTE 或任何东西。视图中提供的数据是为计划应用程序提供数据,运行时非常重要。我不想挣扎,以性能昂贵的视图选择结束。

上面的“原始数据”是一个视图结合了几十个表的数据的结果。我正在寻找一种方法来一次过滤此视图的创建语句中的分组最大值,而无需在其间放置额外的层或视图!

4

3 回答 3

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 小提琴演示

这会给你:

|  PROJECTID |  RESOURCEID | NUM |
----------------------------------
| 1052785922 |   318153743 |  30 |
| 1052785936 |   528513104 |  30 |
| 1052786014 |   528513104 |  30 |
| 1052786021 |   528513104 |  30 |
| 1052786099 | -2097765361 |  20 |
于 2013-01-10T15:18:27.823 回答
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上的演示

于 2013-01-10T17:19:02.023 回答
0

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

感谢大家的提示!

于 2013-01-14T13:02:01.370 回答