将分组和排名结合起来的正确方法是什么?

时间:2012-04-18 20:41:15

标签: tsql sql-server-2008-r2

我已经有了一个按日分解的视图(ByDay在下面的查询中)。

现在我想对其进行过滤,以便在广告系列位于前10个创收广告系列中时,结果中会包含一行。

我得到了我想要的东西,但我有一种感觉,我可能会跳过明显/正确的方式来完成这个过程。

WITH T AS (
    SELECT
     ByDay.[Day]
    ,ByDay.[Campaign Name]
    ,ByDay.[Revenue USD]
    FROM ByDay
    WHERE ByDay.[Period]='Mar 2012'
),
TT AS (
    SELECT
     ByDay.[Campaign Name]
    ,SUM(ByDay.[Revenue USD]) [Sum Revenue USD]
    FROM ByDay
    WHERE ByDay.[Period]='Mar 2012'
    GROUP BY ByDay.[Campaign Name]
)
SELECT * FROM (
SELECT
     T.[Day]
    ,T.[Campaign Name]
    ,T.[Revenue USD]
    ,TT.[Sum Revenue USD]
    ,DENSE_RANK() OVER(ORDER BY TT.[Sum Revenue USD] DESC) AS R
    FROM T
    INNER JOIN TT ON T.[Campaign Name]=TT.[Campaign Name]
) TTT
WHERE R < 11
ORDER BY R

有没有更简单的方法来获得这样的东西?

1 个答案:

答案 0 :(得分:3)

您可以使用SUM([Revenue USD])OVER(Partition By [Campaign Name])获取每个Campaign Name的总和。那你只需要一个CTE:

http://msdn.microsoft.com/en-us/library/ms189461.aspx

WITH T AS (
    SELECT
     ByDay.[Day]
    ,ByDay.[Campaign Name]
    ,ByDay.[Revenue USD]
    ,SUM(ByDay.[Revenue USD]) OVER(Partition By ByDay.[Campaign Name]) [Sum Revenue USD] 
    FROM ByDay
    WHERE ByDay.[Period]='Mar 2012'
)
SELECT * FROM (
SELECT
     T.[Day]
    ,T.[Campaign Name]
    ,T.[Revenue USD]
    ,T.[Sum Revenue USD]
    ,DENSE_RANK() OVER(ORDER BY T.[Sum Revenue USD] DESC) AS R
    FROM T
) TTT
WHERE R < 11
ORDER BY R