2013-08-13 2 views
20

Je comprends que je peux utiliser des variables dans l'ordre par l'article de requêtes SQL comme ceci:Utilisation des variables pour asc et desc afin de

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

Mais comment puis-je utiliser des variables pour les sections asc et desc trop ?

+1

Êtes-vous prêt à utiliser SQL dynamique? Si ce n'est pas le cas, le seul moyen est d'avoir 4 cas dans votre commande, un pour la colonne et un pour la commande. –

+0

Notant que les colonnes de tri d'OP ne semblent pas être * char - meilleure référence pour les doublons possibles ici: http: //stackoverflow.com/questions/1147763/dynamic-order-direction et http://stackoverflow.com/questions/848340/descending-ascending-parameter-to-a-stored-procedure – StuartLC

Répondre

33

sans Dynamic SQL chaque option, il est à l'article par exemple:

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

Essayez celui -

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

En supposant que vos @var3 variables magasins 'ASC' ou 'DESC' mots-clés, vous pouvez écrire quelque chose comme ceci:

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

Qu'arrive-t-il s'il a besoin de la première et de la deuxième clés? un «ASCENDING» et l'autre «DESCENDING»? il aurait besoin de 2 vars, un pour chaque touche –

+0

@LuisLL - True. Je n'ai pas pensé à ça :) Je pensais que 'priority' ou' report_date' seraient triés. Mais devrait avoir l'idée ... –

7

Vous pouvez trier dynamiquement sur plusieurs types en introduisant un multiplier hack au Order by. La mise en œuvre dépendra de vous être en mesure de convertir chaque champ sortable à un champ entier, comme ceci:

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

Modifier

Juste pour clarifier les choses, comme par point de @t-clausen.dk , le piratage dépend d'une conversion vers un type numérique croissant représentant l'ordre. par exemple. Si vous avez besoin d'une résolution plus élevée sur un DATETIME pour vous assurer que le composant temporel est également pris en compte dans le tri, le INT @OrderHack peut être remplacé par un FLOAT ou DECIMAL etc. Avertissement: L'utilisation de cette technique pour trier les colonnes *CHAR peut être difficile, surtout si le cas et la sensibilité d'accent est prise en compte.

+1

Mignon! belle astuce –

+0

fantastique .... !! –

+1

cela ne fonctionnera pas lorsque var1 = 'report_date'. Si report_date est la date du type de colonne, la conversion échouera. Si report_date est un datetime, il sera trié par date, mais pas par heure. Il ne fonctionnera que lorsque report_date ne contient pas de temps –

Questions connexes