2013-08-13 18 views
20

ho capito che posso usare le variabili in ordine per sezione di query SQL come questo:Utilizzo delle variabili per asc e desc in modo da

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

Ma come faccio a utilizzare le variabili per le sezioni asc e desc troppo ?

+1

Sei disposto a utilizzare SQL dinamico? In caso contrario, l'unico modo sarà quello di avere 4 casi nel tuo ordine, uno per la colonna e uno per l'ordine. –

+0

Notando che le colonne di ordinamento dell'OP non sembrano essere * char - migliore riferimento per possibili duplicati qui: http: //stackoverflow.com/questions/1147763/dynamic-order-direction e http://stackoverflow.com/questions/848340/discendente-ascendente-parametro-a-uno-stored-procedure – StuartLC

risposta

33

senza Dynamic SQL ogni opzione è la clausola per esempio:

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

Provate questo -

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

Supponendo che la variabile @var3 negozi 'ASC' o 'DESC' parole chiave, è possibile scrivere qualcosa di simile:

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

cosa succede se ha bisogno di primo e secondo tasto? uno 'ASCENDING' e l'altro' DISCENDING'? avrebbe bisogno di 2 vars, uno per ogni chiave –

+0

@LuisLL - True. Non ci ho pensato :) Stavo pensando che 'priority' o' report_date' saranno ordinati. Ma dovrebbe avere l'idea ... –

7

È possibile ordinare dinamicamente su molti tipi introducendo un multiplier hack su Order by. L'implementazione dipenderà da voi di essere in grado di convertire ogni campo ordinabile ad un campo intero, in questo modo:

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

Modifica

solo per chiarire, come da @t-clausen.dk s' punto , l'hack dipende da una conversione in un tipo numerico crescente che rappresenta l'ordine. per esempio. se è necessaria una risoluzione più elevata su unper garantire che il componente orario sia considerato nell'ordinamento, lo INT @OrderHack può essere sostituito con un FLOAT o DECIMAL. Avvertenza: l'utilizzo di questa tecnica per ordinare le colonne *CHAR potrebbe essere difficile, soprattutto nel caso e la sensibilità di accento è presa in considerazione.

+1

Carino! bel trucco –

+0

fantastico .... !! –

+1

questo non funzionerà quando var1 = 'report_date'. Se report_date è il tipo di colonna data, la conversione fallirà. Se report_date è un datetime verrà ordinato per data, ma non per ora. Funzionerà solo quando report_date non contiene il timepart –

Problemi correlati