2010-10-07 9 views
12

pisanie procedury przechowywanej w MS SQL Server 2008 R2, chcę unikać DSQL ...Warunkowo SQL ORDER BY ASC/DESC dla alfa kolumn

Chciałbym metodę sortowania (ASC lub DESC) do warunkowy.

Teraz z kolumny numerycznej chciałbym po prostu użyć instrukcji case i neguje wartość naśladować ASC lub DSC ... Czyli:

... ORDER BY CASE @OrderAscOrDesc WHEN 0 THEN [NumericColumn] ELSE -[NumericColumn] END ASC 

Co jest odpowiednia metoda robi to z kolumna alfa?

EDYTOWANIE: Pomyślałem o sprytnie, ale wydaje się to niewiarygodnie nieefektywne ... Mógłbym wstawić uporządkowaną kolumnę alfy do tabeli tymczasowej z autonumerą, a następnie posortować według autonumeru za pomocą metody opisanej powyżej.

EDIT2:

Co myślicie o tym podejściu?

ORDER BY CASE @OrderAscOrDesc WHEN 0 THEN [AlphaColumn] ELSE '' END ASC, 
CASE @OrderAscOrDesc WHEN 0 THEN '' ELSE [AlphaColumn] END DESC 

ja nie wiem, czy zmuszanie rodzaj sprawie jednolitego kolumnie jest bardziej wydajny niż wynikające z posortowanych ciągów liczb choć

Odpowiedz

27

jedna opcja

;WITH cQuery AS 
(
    SELECT 
     *, 
     ROW_NUMBER() OVER (ORDER BY SortColumn) AS RowNum 
    FROM 
     MyTable 
) 
SELECT 
    * 
FROM 
    cQuery 
ORDER BY 
    RowNum * @Direction --1 = ASC or -1 = DESC 

Or przypadek, który IMHO jest nieco brzydszy

ORDER BY 
    CASE WHEN 'ASC' THEN SortColumn ELSE '' END ASC, 
    CASE WHEN 'DESC' THEN SortColumn ELSE '' END DESC 
+0

mądry, bardzo podobny do mojego rozwiązania napisałem w edycji. Mam nadzieję na coś bardziej wydajnego niż wyprowadzenie kolejnej posortowanej kopii danych tylko po to, aby utworzyć porządek sortowania numerycznego .... – Matthew

+0

@Matthew PK: musisz albo zastąpić ciąg dla odpowiedniej liczby, albo dodać fałszywe sortowania dla non odpowiednie przypadki. Nic * naprawdę * sprytnie Obawiam się – gbn

+0

Co sądzisz o podejściu "dwa klauzule ORDER BY" w mojej drugiej edycji? – Matthew

1

Jest to jeden z tych przypadków, w których konkretne rozwiązania mogą być lepsze do standardowych, zwłaszcza gdy mamy do czynienia z dużymi ilościami danych. Chciałbym:

IF @OrderAscOrDesc = 0 THEN BEGIN 
    SELECT ... 
    FROM ... 
    ORDER BY [AlphaColumn] ASC 
END ELSE BEGIN 
    SELECT ... 
    FROM ... 
    ORDER BY [AlphaColumn] DESC 
END 

Jeśli masz indeks [AlphaColumn], użytkownik może czasami lepszy plan z bardziej konkretnego zapytania, niż z ogólnej jednym uniwersalnym wszystko jedno.

Edycja: aby ułatwić ponowne wykorzystanie kodu, można owinąć wybierz w UDF inline - będzie wykonywać równie dobrze:

IF @OrderAscOrDesc = 0 THEN BEGIN 
    SELECT ... 
    FROM YourInlineUdf(...) 
    ORDER BY [AlphaColumn] ASC 
END ELSE BEGIN 
    SELECT ... 
    FROM YourInlineUdf(...) 
    ORDER BY [AlphaColumn] DESC 
END 
+0

zgadzam się z zasadą you” ve przedstawione. W mojej konkretnej aplikacji wolałbym tego nie robić, ponieważ zapytanie jest stosunkowo długie i wykorzystuje kilka sprzężeń. Moją obawą byłoby powielenie kodu sześciokrotnie, utrudniając utrzymanie i przyszłe aktualizacje. – Matthew

+0

@Matthew PK: aby ułatwić ponowne użycie kodu, możesz zawinąć swój wybór w wbudowany UDF - będzie działał równie dobrze –