2013-08-13 5 views
20

Ich verstehe, dass ich Variablen in der Reihenfolge von Abschnitt von SQL-Abfragen wie folgt verwendet werden: zuVariablen für asc und ab, um unter Verwendung von

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

Aber wie verwende ich Variablen für die asc und desc Abschnitte ?

+1

Sind Sie bereit, dynamisches SQL zu verwenden? Wenn nicht, dann ist der einzige Weg, 4 Fälle in Ihrer Bestellung zu haben, einen für die Spalte und einen für die Bestellung. –

+0

Beachten Sie, dass die Sortierspalten von OP nicht * char sind - bessere Referenz für mögliche Duplikate hier: http: //stackoverflow.com/questions/1147763/dynamic-order-direction und http://stackoverflow.com/questions/848340/absteigend-aufsteigend-Parameter-zu-gespeichert-Prozedur – StuartLC

Antwort

33

ohne Dynamic SQL jede Möglichkeit, es Klausel zum Beispiel ist:

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

Versuchen Sie dieses -

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

Ihre Variable @var3 speichert 'ASC' oder 'DESC' Schlüsselwörter Unter der Annahme, können Sie so etwas schreiben:

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

Was passiert, wenn er die erste und zweite Taste benötigt? ein 'ASCENDING' und das andere' Descending'? er würde 2 vars benötigen, einen für jeden Schlüssel –

+0

@LuisLL - True. Daran habe ich nicht gedacht :) Ich habe mir gedacht, dass 'priority' oder' report_date' sortiert werden. Aber sollte die Idee bekommen ... –

7

Sie können dynamisch nach vielen Typen sortieren, indem Sie multiplier hack in die Order by eingeben. Die Umsetzung hängt von Ihnen jedes sortierbar Feld zu einem Integer-Feld wie so zu konvertieren, in der Lage:

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

bearbeitet

Nur um zu klären, wie pro @t-clausen.dk ‚s Punkt , der Hack ist abhängig von einer Umwandlung zurück in einen zunehmenden numerischen Typ, der die Reihenfolge repräsentiert. z.B. Wenn Sie eine höhere Auflösung auf DATETIME benötigen, um sicherzustellen, dass die Zeitkomponente auch in der Sortierung berücksichtigt wird, kann die INT @OrderHack durch eine FLOAT oder DECIMAL usw. ersetzt werden. Vorbehalt: Die Verwendung dieser Technik zum Sortieren nach *CHAR Spalten kann eine Herausforderung darstellen, besonders wenn und Akzentempfindlichkeit wird berücksichtigt.

+1

Cute! schöner Trick –

+0

fantastisch .... !! –

+1

dies wird nicht funktionieren, wenn var1 = 'report_date'. Wenn report_date das Datum des Spaltentyps ist, schlägt die Konvertierung fehl. Wenn report_date ein Datum ist, wird es nach Datum, aber nicht nach Zeit sortiert. Es funktioniert nur, wenn report_date nicht timepart –

Verwandte Themen