开发者

Return a subset of rows with a complex order by in T-SQL

I have a stored proc select statement that lookes like that:

SELECT
    p.ID AS ID,
    p.Title AS Title,
    p.Text AS Text,
    p.CategoryID AS CategoryID,
    p.PostDate AS PostDate,
    p.Author AS Author,
    p.AuthorID AS AuthorID,
    p.IsApproved AS IsApproved,
    p.Rating AS Rating,
    p.RatesCount AS RatesCount,
    t.Text AS CategoryNameTranslation,
    p.IsEventPost AS IsEventPost,
    p.EventStart AS EventStart,
    p.EventEnd AS EventEnd,
    p.EventRegionID AS EventRegionID,
    p.EventAddress AS EventAddress
FROM
    Posts AS p
INNER JOIN
    Categories AS c
    ON c.ID = p.CategoryID
INNER JOIN
    Translations AS t
    ON c.TranslationID = t.ID
WHERE
    p.ID = CASE WHEN @ID != 0 THEN @ID ELSE p.ID END AND -- In case if ID given
    p.IsApproved = CASE WHEN @Approved != -1 THEN @Approved ELSE p.IsApproved END AND -- In case of approved status given
    t.Language = @LangID
ORDER BY
    CASE @OrderDirection
        WHEN 'Desc' THEN 
            CASE @OrderBy
                WHEN 'PostDate' THEN p.PostDate
            END
    END
    DESC,
    CASE @OrderDirection
        WHEN 'Asc' THEN 
            CASE @OrderBy
                WHEN 'PostDate' THEN p.PostDate 
            END
    END
    ASC;

I 开发者_开发百科need to return a limited number of rows, but the ROW_NUMBER function requires an ORDER BY expression that is pretty complex here and it will be modified multiple times. Can the expression be somehow referenced from the main select statement or i just have to copy everything into the function's parameter?


I don't understand why you regard putting the ORDER BY into ROW_NUMBER as any more complex than putting it at the end of the query?

;WITH cte AS
(
SELECT
    p.ID AS ID,
    p.Title AS Title,
    p.Text AS Text,
    p.CategoryID AS CategoryID,
    p.PostDate AS PostDate,
    p.Author AS Author,
    p.AuthorID AS AuthorID,
    p.IsApproved AS IsApproved,
    p.Rating AS Rating,
    p.RatesCount AS RatesCount,
    t.Text AS CategoryNameTranslation,
    p.IsEventPost AS IsEventPost,
    p.EventStart AS EventStart,
    p.EventEnd AS EventEnd,
    p.EventRegionID AS EventRegionID,
    p.EventAddress AS EventAddress,
    ROW_NUMBER() OVER (
                ORDER BY
                    CASE @OrderDirection
                        WHEN 'Desc' THEN 
                            CASE @OrderBy
                                WHEN 'PostDate' THEN p.PostDate
                            END
                    END
                    DESC,
                    CASE @OrderDirection
                        WHEN 'Asc' THEN 
                            CASE @OrderBy
                                WHEN 'PostDate' THEN p.PostDate 
                            END
                    END
                    ASC
) AS RN
FROM
    Posts AS p
INNER JOIN
    Categories AS c
    ON c.ID = p.CategoryID
INNER JOIN
    Translations AS t
    ON c.TranslationID = t.ID
WHERE
    p.ID = CASE WHEN @ID != 0 THEN @ID ELSE p.ID END AND -- In case if ID given
    p.IsApproved = CASE WHEN @Approved != -1 THEN @Approved ELSE p.IsApproved END AND -- In case of approved status given
    t.Language = @LangID
) 
SELECT * 
FROM cte 
WHERE RN BETWEEN 11 AND 20
ORDER BY RN;


SELECT TOP 10
....
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜