Помогите с ORDERING ROW_NUMBER OVER Count в порядке убывания? - PullRequest
0 голосов
/ 12 ноября 2009

Я использую функцию ROW_NUMBER (), введенную в SQL SERVER 2005, для возврата постраничного набора результатов. Запрос работает, как и ожидалось, но у меня есть одна проблема. То, что я хотел бы сделать, это вернуть результаты в порядке убывания в порядке убывания. Вот запрос и ниже я приведу небольшое описание:

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. ЗАКАЗАТЬ По cnt desc упорядочивает результаты по их количеству в порядке убывания, но только для 10 записей, которые он выбирает. Я знаю, что это потому, что RowNum заказывается a.Column1, который не считается. В идеале я хотел бы заказать RowNum по графу, так что-то вроде этого:

ROW_NUMBER () OVER (ORDER BY Count (*)) как RowNum

Вышеописанное выполняется, но это занимает вечность (17+ минут).

В качестве примечания, dbo.f_GetDataCount (a.column3) как cnt возвращает общее количество записей на основе a.column3, поэтому я попытался:

ROW_NUMBER () OVER (ORDER BY dbo.f_GetDataCount (a.column3) как RowNum, но это также длилось вечно.

Если я на самом деле путаю это больше, чем то, что есть, я приведу небольшой пример. Если я установлю StartRowIndex равным 1, он вернет 10 записей, а первая запись будет иметь 10 000.

Если я тогда установлю StartRowIndex равным 11, он вернет следующие 10 записей, и первая запись будет иметь 15 000.

Что на самом деле должно возвращать, так это запись с 15 000 первыми, независимо от того, что такое StartRowIndex.

Помощь очень ценится.

Вот код функции:

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 Ответ

4 голосов
/ 12 ноября 2009

Спасибо за публикацию кода UDF - попробуйте вместо использования встроенного скалярного UDF. Должно быть намного быстрее, чем заказ ROWNUBMER (OVER dbo.fn_GetDataCount ()).

Если у вас все еще есть неоптимальная производительность, вероятно, что индексация вступит в игру, или вы можете посмотреть на материализацию количества значений столбца 3 (мы можем обсудить варианты здесь, если это все еще необходимо решить, просто перепечатайте).

РЕДАКТИРОВАТЬ: К сожалению, добавили "desc" к порядку в предложении over, так как вы хотите, чтобы они нисходили - также немного отредактировали скаляры ...

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...