Renvoyer une valeur booléenne sur l'instruction SQL Select


144

Comment renvoyer une valeur booléenne sur l'instruction SQL Select?

J'ai essayé ce code:

SELECT CAST(1 AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)

Et il ne revient que TRUEsi le UserIDexiste sur la table. Je veux qu'il revienne FALSEsi le UserIDn'existe pas sur la table.


3
Quels dbms? Les détails de SQL diffèrent.
joshp

SQL Server ne prend pas en charge un type booléen, par exemple SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- entraîne une erreur, c'est CAST(1 AS BIT)-à- dire n'est pas le même TRUE logique.
jour du

Réponses:


253

Ce que vous avez là ne renverra aucune ligne si l'utilisateur n'existe pas. Voici ce dont vous avez besoin:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END

2
pourquoi utiliser un astérisque, il est préférable d'utiliser à la 1place de *.

7
@ robertpeter07 - Les deux sont équivalents, mais *c'est plus idiomatique. Voir cette question .
Chad

Si vous utilisez une boucle WHILE, devrais-je la mettre entre accolades {} juste après le 'WHILE'?
full_prog_full

Pouvez-vous ajouter un nom de colonne à la valeur renvoyée?
xMetalDetectorx

3
@xMetalDetectorx Cela a fonctionné pour moi d'ajouter le nom de la colonne (la AS boolpartie est très importante):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo

31

Peut-être quelque chose du genre:

SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM dummy WHERE id = 1;

http://sqlfiddle.com/#!3/5e555/1


6
Cela renvoie une chaîne, pas une valeur booléenne
OMG Ponies

C'est une bonne pratique d'inclure un nom de colonne - SELECT CAST (CASE WHEN COUNT (*)> 0 THEN 1 ELSE 0 END AS BIT) en tant que mycolumnname FROM dummy WHERE id = 1
Diego Alves

22

Étant donné que généralement 1 = trueet 0 = false, tout ce que vous avez à faire est de compter le nombre de lignes et de convertir en a boolean.

Par conséquent, votre code publié n'a besoin que d'une COUNT()fonction ajoutée:

SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)

8
Faire le Exists(test est beaucoup plus rapide que de faire un Count(1)test sur des tables avec un grand nombre de lignes.
Scott Chamberlain

5
Probablement. Je n'ai fait aucune revendication de performance dans ma réponse, juste le changement de code minimal pour atteindre ce que l'OP voulait. Cependant, si la colonne UserIDest indexée (ou est même le PK), vous allez sûrement directement à la ligne unique qui existe (ou non).
Stewart

9

Utilisez 'Exists' qui renvoie 0 ou 1.

La requête sera comme:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)

10
Erreur: "Syntaxe incorrecte à côté du mot clé" EXISTS "." sqlfiddle.com/#!18/ef905/18
JoePC

8
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

Si count (*) = 0 renvoie faux. Si count (*)> 0 renvoie vrai.


4

Je fais ça comme ça:

SELECT 1 FROM [dbo].[User] WHERE UserID = 20070022

Étant donné qu'un booléen ne peut jamais être nul (du moins dans .NET), il doit être défini par défaut sur false ou vous pouvez le définir vous-même si la valeur par défaut est true. Cependant 1 = vrai, donc null = faux, et aucune syntaxe supplémentaire.

Remarque: j'utilise Dapper comme micro orm, j'imagine qu'ADO devrait fonctionner de la même manière.


Ma réponse préférée et la plus concise à ce jour. Fiddle of all answers: sqlfiddle.com/#!18/ef905/18
JoePC

"Voir comme un booléen ne peut jamais être nul (du moins dans .NET)." (bool?) est un bool nullable.
Andrew Dennison le

1

Notez un autre problème équivalent: créer une requête SQL qui retourne (1) si la condition est satisfaite et un résultat vide dans le cas contraire. Notez qu'une solution à ce problème est plus générale et peut facilement être utilisée avec les réponses ci-dessus pour atteindre la question que vous avez posée. Puisque ce problème est plus général, je prouve sa solution en plus des belles solutions présentées ci-dessus à votre problème.

SELECT DISTINCT 1 AS Expr1
FROM [User]
WHERE (UserID = 20070022)

1

Pour ceux d'entre vous qui souhaitent obtenir la valeur ajoutée d'un nom de colonne personnalisé, cela a fonctionné pour moi:

CAST(
    CASE WHEN EXISTS ( 
           SELECT * 
           FROM mytable 
           WHERE mytable.id = 1
    ) 
    THEN TRUE 
    ELSE FALSE 
    END AS bool) 
AS "nameOfMyColumn"

Vous pouvez ignorer les guillemets doubles du nom de la colonne au cas où vous ne seriez pas intéressé par le respect de la casse du nom (dans certains clients).

J'ai légèrement modifié la réponse de @ Chad à ce sujet.


Msg 102, niveau 15, état 1, ligne 8 Syntaxe incorrecte près de 'CAST'. Msg 156, niveau 15, état 1, ligne 12 Syntaxe incorrecte près du mot-clé «ALORS».
ShaneC

@ShaneC J'ai testé ce code sur PostgreSQL 9.X et cela a bien fonctionné. Quel serveur utilisez-vous?
Lucio Mollinedo le

0
DECLARE @isAvailable      BIT = 0;

IF EXISTS(SELECT 1  FROM [User] WHERE (UserID = 20070022))
BEGIN
 SET @isAvailable = 1
END

La valeur booléenne initialement isAvailable est définie sur 0

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.