有关ORDERING ROW_NUMBER的详细信息,请参阅降序中的计数?

时间:2009-11-12 17:09:02

标签: sql-server tsql

我正在使用SQL SERVER 2005中引入的ROW_NUMBER()函数来返回一组分页结果。查询按预期工作,但我有一个问题。我想要做的是按降序返回计数排序的结果。这是查询,下面我将给出一些描述:

DECLARE @StartRowIndex INT
DECLARE @MaximumRows INT

SET @StartRowIndex = 1
SET @MaximumRows = 10

;WITH Data AS (SELECT
        ROW_NUMBER() OVER (ORDER BY a.column1) as RowNum,
        a.column1, a.column2, dbo.f_GetDataCount(a.column3) as cnt
        FROM dbo.table1 a
        INNER JOIN dbo.table2 b on b.column4 = a.column4
        INNER JOIN dbo.table3 c on c.column5 = a.column5
        LEFT OUTER JOIN dbo.table4 d on d.column6 = a.column6
        WHERE 1=1  AND a.column7 IN (1)
)


SELECT RowNum,column1,
   column2,cnt
FROM
Data
WHERE RowNum BETWEEN @StartRowIndex AND (@StartRowIndex + @MaximumRows) - 1
ORDER BY cnt desc
  1. 我知道最高计数在100,000+范围内。
  2. ORDER通过cnt desc按结果按降序排序,但是 仅适用于它提取的10条记录。我知道这是因为RowNum是由a.Column1订购的,这不是计数。理想情况下,我想通过Count来命令RowNum,所以像这样:
  3. ROW_NUMBER()OVER(按Count(*)排序)为RowNum

    以上运行,但需要永远(17分钟以上)。

    作为附注,dbo.f_GetDataCount(a.column3)作为cnt返回基于a.column3的记录总数,所以我尝试了:

    ROW_NUMBER()OVER(订购dbo.f_GetDataCount(a.column3)为RowNum,但这也是永远的。

    如果我真的比这更令人困惑,我会举一个例子。如果我将StartRowIndex设置为1,它将返回10条记录,第一条记录将有10,000条记录。

    如果我将StartRowIndex设置为11,它将返回接下来的10条记录,第一条记录将有15,000条记录。

    实际应该返回的是无论StartRowIndex是什么,首先记录的是15,000。

    非常感谢帮助。

    以下是该函数的代码:

    CREATE FUNCTION [dbo].[f_GetDataCount] 
    (
    -- Add the parameters for the function here
    @column3 nvarchar(10)
    )
    RETURNS int
    AS
    BEGIN
    -- Declare the return variable here
    DECLARE @Result int
    
    -- Add the T-SQL statements to compute the return value here
    SELECT @Result = COUNT(a.column3) FROM dbo.table1 a
    where a.column3 = @column3
    
    -- Return the result of the function
    RETURN @Result
    
    END
    

1 个答案:

答案 0 :(得分:4)

感谢您发布UDF代码 - 尝试使用内联标量UDF。应该比ROWNUBMER(OVER dbo.fn_GetDataCount())的订购快得多。

如果你仍然有次优的性能,可能会发生索引,或者你可以看看中间实现column3值的计数(如果仍然需要解决,我们可以在这里讨论选项,只需重新发布)。

编辑:哎呀,在over子句中添加了“desc”,因为你希望它们下降 - 同样,编辑了一些标量...

DECLARE @StartRowIndex INT
DECLARE @MaximumRows INT
DECLARE @EndRowIndex INT

SELECT @StartRowIndex = 1, @MaximumRows = 10
SELECT @EndRowIndex = (@StartRowIndex + @MaximumRows) - 1


;WITH Data1 as (
    SELECT  a.column3 as c3, count(*) as frequency
    from    dbo.table1 a
    group by a.column3
),
Data AS (SELECT
        ROW_NUMBER() OVER (ORDER BY coalesce(d.frequency,0) desc) as RowNum,
        a.column1, a.column2, d.frequency as cnt
        FROM dbo.table1 a
        INNER JOIN dbo.table2 b on b.column4 = a.column4
        INNER JOIN dbo.table3 c on c.column5 = a.column5
        LEFT OUTER JOIN dbo.table4 d on d.column6 = a.column6
        LEFT OUTER JOIN Data1 d
        on a.column3 = d.c3
        WHERE 1=1  AND a.column7 IN (1)
)
SELECT RowNum,column1,
   column2,cnt
FROM
Data
WHERE RowNum BETWEEN @StartRowIndex AND @EndRowIndex
ORDER BY cnt desc