可以简化此查询

时间:2012-12-05 12:04:32

标签: sql sql-server sql-server-2008-r2

修改

以下是我的数据示例:

 create TABLE #Table 
(
    [Market] VARCHAR(100),
    [Operator] VARCHAR(100),
    [Date] DATE,
    [Num Registrations] INT,
    [Num Active] INT,
    [Num Accepted Purchases] INT
)

INSERT INTO #Table VALUES
('Market1','Operator1','2012-12-01',2,4,7),
('Market1','Operator2','2012-12-01',3,5,7),
('Market1','Operator3','2012-12-01',1,2,7),
('Market2','Operator4','2012-12-01',2,1,7),
('Market2','Operator5','2012-12-01',0,4,7),
('Market3','Operator6','2012-12-01',2,44,7)

我有以下脚本:

SELECT 
    a.[Market],
    a.[Operator],
    a.[Date],
    a.[Num Registrations],
    a.[Num Active],
    a.[Num Accepted Purchases],
    [rnk] = b.rnk
FROM 
    #Table a
    INNER JOIN 
        (
        SELECT 
            [Market],
            [rnk] = RANK() OVER (ORDER BY SUM([Num Registrations] + [Num Active]))
        FROM #Table
        GROUP BY [Market]
        ) b
        ON 
          a.[Market] = b.[Market]
GROUP BY
    a.[Market],
    a.[Operator],
    a.[Date],
    a.[Num Registrations],
    a.[Num Active],
    a.[Num Accepted Purchases],
    b.rnk

以上工作正常,但是sub-query让我过于复杂;我可以直接在主查询的RANK子句中使用SELECT函数吗?

3 个答案:

答案 0 :(得分:1)

我认为最后一组是多余的,但我看不到避免子查询的方法..

我不确定以下内容是否更有效,您必须尝试使用​​您的数据,但它更容易阅读:

SELECT 
    a.[Market],
    a.[Operator],
    a.[Date],
    a.[Num Registrations],
    a.[Num Active],
    a.[Num Accepted Purchases],
    [rnk] = DENSE_RANK() OVER (ORDER BY NumToRankOver)
FROM xxx.dbo.tb_r12044dxx_yyyy a
INNER 
JOIN 
(
    SELECT 
    [Market],
    SUM([Num Registrations] + [Num Active]) AS NumToRankOver
    FROM xxx.dbo.tb_r12044dxx_yyyy
    GROUP BY [Market]
) b
    ON  a.[Market] = b.[Market]

答案 1 :(得分:1)

以下是cte的样子。

 DECLARE @Table TABLE
(
    [Market] VARCHAR(100),
    [Operator] VARCHAR(100),
    [Date] DATE,
    [Num Registrations] INT,
    [Num Active] INT,
    [Num Accepted Purchases] INT
)

INSERT INTO @Table VALUES
('Market1','Operator1','2012-12-01',2,4,7),
('Market2','Operator2','2012-12-01',3,5,7),
('Market3','Operator3','2012-12-01',1,2,7),
('Market4','Operator4','2012-12-01',2,1,7),
('Market5','Operator5','2012-12-01',0,4,7),
('Market6','Operator6','2012-12-01',2,44,7)

--with cte
    ;WITH Cte_Rank AS
    (
        SELECT 
             a.[Market],
             RANK() OVER (ORDER BY SUM(a.[Num Registrations] + a.[Num Active])) [Rnk]
        FROM @Table a GROUP BY a.Market 
    )
    SELECT 
        a.[Market],
        a.[Operator],
        a.[Date],
        a.[Num Registrations],
        a.[Num Active],
        a.[Num Accepted Purchases],
        c.Rnk
    FROM @Table a
    INNER JOIN Cte_Rank c ON c.Market = a.Market


--The only way to avoid subquery is to get rid of the "SUM" aggregate       
    SELECT 
        a.[Market],
        a.[Operator],
        a.[Date],
        a.[Num Registrations],
        a.[Num Active],
        a.[Num Accepted Purchases],
         RANK() OVER (ORDER BY a.[Num Registrations] + a.[Num Active]) [Rnk]
    FROM @Table a

答案 2 :(得分:1)

是的,您根本不需要进行显式连接:

SELECT distinct
    a.[Market],
    a.[Operator],
    a.[Date],
    a.[Num Registrations],
    a.[Num Active],
    a.[Num Accepted Purchases],
    [rnk] = dense_rank() over (order by tot, market)
FROM (select a.*,
             sum(a.[Num Registrations] + a.[Num Active]) over (partition by market) as tot
      from xxx.dbo.tb_r12044dxx_yyyy a
     ) a

如果您没有重复项,则可以从distinct删除select