1
votes

La syntaxe d'expression de cas dans la clause where rend le problème que la sous-requête a renvoyé plus d'une valeur lorsque la sous-requête est utilisée comme une expression

 Here is my table recored

Je veux écrire du code qui renvoie tous les enregistrements de la table si je sélectionne le code Branch comme vide.

Mais quand je sélectionne Branch Code ceci doit renvoyer l'enregistrement uniquement pour une succursale spécifique.

BRANCHCODE in () 

Au-dessus du code retourne très bien.

Maintenant, je veux utiliser cette condition dans l'instruction case de la clause where. Le code est donné ci-dessous:

set @BRANCHCODE = ''

Il renvoie très bien lorsque je définis un code de branche spécifique. Tels que

set @BRANCHCODE='1001'

Mais son retour est erroné:

La sous-requête a renvoyé plus d'une valeur. Ceci n'est pas autorisé lorsque la sous-requête suit =,! =, ,> = Ou lorsque la sous-requête est utilisée comme expression.

Quand j'utilise

    declare 
   @BRANCHCODE varchar(4)
   set @BRANCHCODE=''
   SELECT  ID,BRANCHCODE,BRANCHNAME,DEPARTMENTCODE,DEPARTMENTNAME FROM RATINGLOGS
   WHERE BRANCHCODE in (Case when @BRANCHCODE='' then (SELECT  BRANCHCODE FROM RATINGLOGS) else  @BRANCHCODE  end)

** Il est mentionné que j'utilise

   declare 
   @BRANCHCODE varchar(4)
   set @BRANCHCODE=''
   if (@BRANCHCODE='')
   begin
    SELECT  ID,BRANCHCODE,BRANCHNAME,DEPARTMENTCODE,DEPARTMENTNAME FROM RATINGLOGS
   WHERE BRANCHCODE in (SELECT  BRANCHCODE FROM RATINGLOGS)
   end 
   else
   begin
    SELECT  ID,BRANCHCODE,BRANCHNAME,DEPARTMENTCODE,DEPARTMENTNAME FROM RATINGLOGS
   WHERE BRANCHCODE=@BRANCHCODE
   end 

tel que prend en charge plus d'une valeur. Je n'utilise pas (=,! =, ,> =). Mais ça va mal. **

J'ai besoin de l'explication de la question et si c'est possible d'utiliser l'instruction case dans la clause where quel sera le code de réécriture?


3 commentaires

J'ai utilisé Sql-Server


À l'avenir, veuillez étiqueter la base de données correspondante.


votre sous-requête dans (Cas où @BRANCHCODE ne commence pas par SELECT La sous-requête doit toujours être des requêtes complètes


4 Réponses :


1
votes

La condition in est redondante dans la première requête - le branchcode interrogé à partir de ratinglogs doit par définition être dans la liste de tous les branchcodes sélectionnés dans ratinglogs , vous pouvez donc simplement y déposer la clause where .

En gardant cela à l'esprit, vous pouvez réécrire la requête dans le deuxième extrait comme tel:

SELECT id, branchcode, branchname, depatmentcode, departmentname
FROM   ratinglogs
WHERE  @branchcode IN (branchcode, '');


0 commentaires

1
votes

L'instruction case ne peut renvoyer qu'une valeur, donc lorsque vous utilisez ... then (select branchcode from ratinglogs) , elle renvoie toutes les valeurs, et ceci est une erreur.

Si vous voulez combiner la logique des deux requêtes en une seule, vous devez utiliser la logique "case" mais pas la véritable instruction case :

WHERE (
(@BRANCHCODE='' and BRANCHCODE in (SELECT  BRANCHCODE FROM RATINGLOGS))
or
(not @BRANCHCODE='' and BRANCHCODE=@BRANCHCODE)
)


0 commentaires

0
votes

Vous n'avez pas besoin de l'opérateur IN () ici, votre requête peut être comme

SELECT ID,
       BRANCHCODE,
       BRANCHNAME,
       DEPARTMENTCODE,
       DEPARTMENTNAME 
FROM RATINGLOGS
WHERE BRANCHCODE = ''
      OR
      BRANCHCODE IN (SELECT Value FROM STRING_SPLIT(@BRANCHCODE, ','));

Le code ci-dessus retournera toutes les lignes si @BRANCHCODE = '' , et s'il contient une autre valeur, il retournera la ligne spécifique où BRANCHCODE = @BRANCHCODE .

Puisque vous posez des questions sur le Expression CASE , si vous souhaitez utiliser l'opérateur IN () , vous pouvez utiliser l'autre solution par @Mureinik.

Si la variable @BRANCHCODE peut contenir plusieurs valeurs, par exemple: '1001,1002,1003' alors cela ne fonctionnera pas comme prévu, vous devrez diviser la chaîne en lignes.

SELECT ID,
       BRANCHCODE,
       BRANCHNAME,
       DEPARTMENTCODE,
       DEPARTMENTNAME 
FROM RATINGLOGS
WHERE 1 = CASE WHEN @BRANCHCODE = '' THEN 1 ELSE 0 END --@BRANCHCODE = ''
      OR
      BRANCHCODE = @BRANCHCODE;

notez que STRING_SPLIT () n'est disponible que dans les versions de SQL Server 2016+ , si vous ne l'avez pas, vous devez définir le vôtre


0 commentaires

0
votes

vous n'avez besoin d'aucune sous-requête

SELECT  ID,
        BRANCHCODE,
        BRANCHNAME,
        DEPARTMENTCODE,
        DEPARTMENTNAME 
FROM    RATINGLOGS
WHERE   (@BRANCHCODE = '' or BRANCHCODE = @BRANCHCODE)

Cela renverra toutes les lignes si la variable @BRANCHCODE = '' et sinon, il ne retournera que les lignes où BRANCHCODE = @BRANCHCODE

Puisque vous avez déclaré @BRANCHCODE uniquement comme varchar (4), je suppose qu'il ne contiendra toujours qu'une seule valeur.
Si vous en avez besoin pour contenir plus d'un code, cela ne fonctionnera pas


0 commentaires