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.

mrjimoy_05
la source
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
Tchad
la source
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

câble
la source
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)
Stewart
la source
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)
Ananthi
la source
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.

G.Noulas
la source
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.

RandomUs1r
la source
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)
Dean Leitersdorf
la source
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.

Lucio Mollinedo
la source
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

Chamin Thilakarathne
la source