2010-09-05 7 views
1

J'ai une instruction select de procédure stockée qui lookes comme ça:Retour un sous-ensemble de lignes avec un ordre complexe par T-SQL

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; 

je dois retourner un nombre limité de lignes, mais la fonction ROW_NUMBER nécessite une expression ORDER BY assez complexe ici et qui sera modifiée plusieurs fois. Est-ce que l'expression peut être référencée d'une manière ou d'une autre à partir de l'instruction de sélection principale ou simplement copier tout dans le paramètre de la fonction?

Répondre

0

Je ne comprends pas pourquoi vous considérez mettre le ORDER BY en ROW_NUMBER comme plus complexe que de le mettre à la fin de la requête?

;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; 
+0

Si je mets ORDER BY dans ROW_NUMBER, le jeu de résultats sera ordonné comme Il sera spécifié dans l'argument de la fonction? – aikixd

+0

C'est ce que le 'ORDER BY RN' à la fin est pour. –

+0

J'ai compris. Merci! – aikixd

0
SELECT TOP 10 
.... 
+0

Vous supposez que le sous-ensemble qu'ils veulent commencer à la première ligne. –

+0

Eh bien c'est ce que l'OQ a demandé "un nombre limité de rangées". Je suis impatient de découvrir quelles lignes. :) – Hogan

+0

Oui, je devais le mentionner. TOP ne fonctionnera pas pour moi. J'en ai besoin pour la pagination – aikixd