Comment écrire ordre par clause avec plusieurs colonnes dans une instruction case?
ORDER BY CASE WHEN @T='ABC' Then Convert(int,Val) WHEN @T='ABC' Then Convert(nvarchar,Seq) ELSE Seq END ORDER BY CASE WHEN @T='ABC' Then Val,Seq ELSE Seq END
Également essayé
ORDER BY CASE WHEN @T='ABC' Then Val,Seq ELSE Seq END
Également le code ci-dessous renvoie une erreur:
"Cette instruction donne une erreur:" La conversion a échoué lors de la conversion de la valeur nvarchar 'EX-02-60' en type de données int "lorsque la procédure stockée est exécutée."
3 Réponses :
Je pense que ce que vous recherchez est:
ORDER BY CASE WHEN @T='ABC' Then Convert(int,Val) WHEN @T='ABC' Then Convert(nvarchar,Seq) ELSE Seq END
Expliquer pourquoi vos tentatives n'ont pas fonctionné. Premièrement:
WHERE Type = @T ORDER BY CASE WHEN @T='ABC' Then Val,Seq ELSE Sequence END
Un CASE
est une expression qui renvoie une valeur scalaire . Ici, votre WHEN
a essayé de renvoyer 2 valeurs. Ce n'est pas autorisé.
ORDER BY CASE @T WHEN 'ABC' THEN Val END, CASE @T WHEN 'ABC' THEN Seq END, [Sequence];
Comme CASE
renvoie une valeur scalaire, il ne peut renvoyer qu'un seul type de données. L'expression CASE
utilise la précédence du type de données, et int
a une précédence plus élevée que nvarchar
donc Seq
serait implicitement converti en un int
; et je risquerais de penser que cela a échoué.
Cette instruction donne l'erreur: «La conversion a échoué lors de la conversion de la valeur nvarchar 'EX-02-60' en type de données int» lorsque la procédure stockée est exécutée.
Ce ne sera pas le ORDER BY
renvoyant cette erreur @ShradhaR. Il n'y a pas de conversions implicites dans ma solution. Cette erreur provient d'un autre endroit de votre SQL que vous ne nous avez pas fourni.
Une conversion explicite Convert (nvarchar, Seq) ne fonctionnera pas dans ce scénario? sinon, pourriez-vous suggérer une meilleure approche?
Je ne sais pas ce que vous voulez dire ici @ShradhaR. Je n'ai pas de conversion explicite ou implicite dans ma solution. L'erreur que vous obtenez (avec le ORDER BY
que j'ai fourni) n'est pas due à la clause ORDER BY
. C'est ailleurs.
Si vous publiez votre SQL complet , ainsi que DDL dans votre question, nous pouvons vous aider à résoudre ce problème également. Ou peut-être posez-le comme une question distincte.
@sami CASE @T WHEN 'ABC' THEN Val END,
renverra le type de données de Val
. Si Val
est un varchar
, alors c'est le type de données qu'il retournera. Le NULL
serait implicitement converti en varchar
; un NULL
n'a pas le type de données int
par défaut. Sinon, une expression comme SELECT CASE WHEN 1 = 1 THEN 'abc' END
échouerait.
@Sami. . . C'est la bonne solution et cela explique également pourquoi.
Et j'ai reproduit cette logique, @Sami par une méthode différente. Si @T
a une valeur de ABC
'alors les données seront triées (par ordre croissant) par Val
, puis Seq code>, puis enfin
Sequence
. Si @T
a une autre valeur (y compris NULL
), alors les données seront triées par la valeur NULL
(donc pas d'ordre), suivie par alors la valeur NULL
(encore une fois, pas d'ordre), puis Sequence
; ce qui signifie effectivement que les données seront triées par Séquence
. Ce n'est pas parce que l'OP a utilisé la logique CASE ... ELSE
que la solution doit le faire.
@Sami Où voyez-vous un casting dans ma solution? Ni CASE @T WHEN 'ABC' THEN Val END,
ni CASE @T WHEN 'ABC' THEN Seq END,
n'ont de transtypage implicite (ou explicite). Comme je l'ai déjà dit, NULL
n'a pas de type de données par défaut et, dans ce cas, sera CAST
au type de données de Val
et < code> Seq respectivement dans chacune de ces expressions CASE
.
@Sami Je n'ai pas de ELSE
dans ma logique ... Vous semblez avoir mal lu mon SQL. J'ai édité votre violon DB pour montrer quelle est ma logique. J'ai également modifié les exemples de données pour montrer ce qui se passe lorsque @T
n'a pas la valeur 'abc'
: db <> violon
@Larnu C'est faux car maintenant vous allez toujours commander par NN, (séquence dans OP Q)
Euh ... @Sami avez-vous lancé le violon. Notez que les 2 jeux de données ont 2 ordres différents ... J'ai essayé, mais clairement cette conversion est terminée / perdue.
Le type de données de la valeur dans le ORDER BY
doit toujours être le même. Ici, vous obtiendrez l'erreur de conversion car dans le premier cas, le type de données est INT et dans le second, c'est Varchar. SO Pour une manière plus sécurisée, vous pouvez utiliser l'approche suivante
;WITH CTE AS ( SELECT RN_Val = ROW_NUMBER() OVER(ORDER BY Val), RN_Seq = ROW_NUMBER() OVER(ORDER BY Seq), * FROM YourTable ) SELECT * FROM CTE ORDER BY ( CASE @T WHEN 'ABC' THEN RN_Val WHEN 'XYZ' THEN RN_Seq END )
Créons une table qui a vos colonnes
--Fixes-- DECLARE @T VARCHAR(3) = '1'; --Try to change it to ABC too SELECT * FROM T ORDER BY CASE WHEN @T='ABC' THEN Val END, --Take varchar CASE WHEN @T='ABC' THEN Seq -- Take INT ELSE Sequence -- Take INT END; /* IF @T = ABC ORDER BY Val, Seq; NOT Sequence IF @T <> ABC ORDER BY ONLY Sequence */
Maintenant, regardons votre code et apportons ensuite les conditions:
Voici votre code: p >
--You was trying-- DECLARE @T VARCHAR(3) = 'ABC'; --wil works only when @T <> ABC SELECT * FROM T ORDER BY CASE WHEN @T='ABC' THEN Seq END, --Take INT CASE WHEN @T='ABC' THEN Val --Take Varchar ELSE Sequence -- Take INT END;
@T = 'ABC
alors commandez par Val
et Seq
ET NE PAS commandez par Séquence
. @T 'ABC'
alors commandez Seulement avec Séquence
. Si vous exécutez cette requête:
ORDER BY CASE WHEN @T='ABC' Then Val,Seq ELSE Sequence END
Cela générera l'erreur suivante si @T = 'ABC'
p>
Msg 245 Niveau 16 État 1 Ligne 5
La conversion a échoué lors de la conversion de la valeur varchar 'A' en type de données int.
comme vous obtenez
La conversion a échoué lors de la conversion de la valeur nvarchar 'EX-02-60' en type de données int.
Maintenant, voici ce que vous voulez selon les conditions que vous fournissez:
CREATE TABLE T( Val VARCHAR(45), Seq INT, Sequence INT ); INSERT INTO T VALUES ('A', 1, 2), ('C', 2, 1), ('B', 3, 3);
Et voici un Démo en direct
Le code précédent fonctionnait bien pour moi. Je n'ai pas encore testé le dernier que vous avez fourni.
@SRawat Le code précédent fonctionne très bien pour vous car CAST (), mais il ne prend pas la colonne Sequence
dans count.
Comment se fait-il que je n'ai pas de moyen de vous contacter sauf pour SO
Cette tentative est à l'envers. Mettez la casse expression dans ORDER BY.
Je vous ai déjà dit exactement quoi écrire dans un commentaire sur votre autre question lorsque j'ai suggéré ce changement.
OP Je mets à jour ma réponse pour être claire et pour plus de détails et j'inclus également une démo en direct.
@Damien_The_Unbeliever Oui, vous l'avez fait. Mais j'étais confronté à des problèmes de syntaxe et une autre erreur s'est produite. Par conséquent, j'ai ajouté ce poste en tant que chaîne distincte. Bien que cette question reste ouverte, le code a été optimisé mais les performances restent les mêmes et j'ai également mentionné la même chose dans cette question.