2013-08-13 18 views
20

Rozumiem, że mogę używać zmiennych w kolejności według sekcji SQL kwerend jak poniżej:Używanie zmiennych dla ASC i desc w kolejności przez

order by 
case when @var1 = 'priority' then priority end desc, 
case when @var2 = 'report_date' then report_date end asc 

Ale jak mogę używać zmiennych dla sekcjach ASC i desc zbyt ?

+1

Czy chcesz korzystać z dynamicznego SQL? Jeśli nie, jedynym sposobem będzie posiadanie 4 przypadków w zamówieniu przez, jedną dla kolumny i jedną dla zamówienia. –

+0

Zauważając, że kolumny sortowania OP nie wyglądają na * char - lepsze referencje dla możliwych duplikatów tutaj: http: //stackoverflow.com/questions/1147763/dynamic-order-direction i http://stackoverflow.com/questions/848340/malejąco-parametr-do-przechowywanej procedury – StuartLC

Odpowiedz

33

bez Dynamic SQL każda opcja jest klauzula na przykład:

ORDER BY 
    case when @var1 = 'priority asc' THEN priority END ASC , 
    case when @var1 = 'priority desc' then priority end DESC, 
    case when @var2 = 'report_date asc' then report_date end ASC, 
    case when @var2 = 'report_date desc' then report_date end DESC 
4

próbować ten jeden -

DECLARE 
     @column VARCHAR(15) = 'object_id' 
    , @order CHAR(4) = 'DESC' 

DECLARE @SQL NVARCHAR(MAX) 
SELECT @SQL = ' 
SELECT * 
FROM sys.objects 
ORDER BY ' + @column + ' ' + @order 

PRINT @SQL 
EXEC sys.sp_executesql @SQL 
5

Zakładając zmiennej @var3 sklepy 'ASC' lub 'DESC' słów kluczowych, można napisać coś takiego:

order by 
case when @var1 = 'priority' and @var3 = 'DESC' then priority end DESC, 
case when @var1 = 'priority' and @var3 = 'ASC' then priority end ASC, 
case when @var2 = 'report_date' and @var3 = 'ASC' then report_date end ASC, 
case when @var2 = 'report_date' and @var3 = 'DESC' then report_date end DESC 
+0

co się stanie, jeśli będzie potrzebował pierwszego i drugiego klucza? jeden "ASCENDING" i drugi "DESCENDING"? potrzebowałby 2 vars, po jednym na każdy klucz –

+0

@LuisLL - True. Nie pomyślałem o tym :) Myślałem, że albo 'priority' lub' report_date' zostaną posortowane. Ale powinienem wpaść na pomysł ... –

7

Można sortować dynamicznie na wielu typach, wprowadzając multiplier hack do Order by. Realizacja będzie zależeć to, że jesteś w stanie przekształcić każde pole sortable na pole całkowitą, tak:

DECLARE @Var1 NVARCHAR(20); 
DECLARE @Var2 NVARCHAR(3); 
DECLARE @OrderHack INT; 

SET @Var1 = 'priority'; 
SET @Var2 = 'DESC'; 

IF (@Var2 = 'ASC') 
    SET @OrderHack = 1; 
ELSE 
    SET @OrderHack = -1; 

SELECT * 
    FROM SortTable 
    ORDER BY 
     CASE @var1 
      WHEN 'priority' 
       THEN CONVERT(INT, [priority]) * @OrderHack 
      WHEN 'report_date' 
       THEN CONVERT(INT, report_date) * @OrderHack 
     END; 

SqlFiddle here

Edycja

Właśnie w celu wyjaśnienia, jak na @t-clausen.dk „s punkcie , hack jest zależny od konwersji z powrotem na rosnący numeryczny typ reprezentujący kolejność. na przykład Jeśli wymagana jest wyższa rozdzielczość na DATETIME, aby zapewnić uwzględnienie komponentu czasu, to INT @OrderHack może być zastąpiony przez FLOAT lub DECIMAL itd. Zastrzeżenie: Użycie tej techniki do sortowania na kolumnach *CHAR może być trudne, szczególnie w przypadku Uwzględniana jest czułość akcentu.

+1

Sprytnie! fajna sztuczka –

+0

fantastyczna .... !! –

+1

to nie zadziała, gdy var1 = "report_date". Jeśli data_raportu jest datą typu kolumny, konwersja się nie powiedzie. Jeśli data_raportu jest datetime, zostanie uporządkowane według daty, ale nie według czasu. Będzie działać tylko wtedy, gdy report_date nie zawiera timepartu –

Powiązane problemy