views:

18

answers:

2

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?

A: 
SELECT TOP 10
....
Hogan
You're assuming the subset they want starts at the first row.
Martin Smith
Well that is what the OQ asked for "a limited number of rows". I look forward to finding out which rows. :)
Hogan
Yes, I had to mention that. TOP will not work for me. I need it for pagination
You can do pagination with top -- just 3 sub-queries with a top in each and an order reversal. Ah, the days before row_number() where top was king.
Hogan
A: 

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;
Martin Smith
If I put the ORDER BY into ROW_NUMBER the result set will ordered as It will be specified in the function argument?
That's what the `ORDER BY RN` at the end is for.
Martin Smith
Got it. Thanx!!