Restituisce valore booleano sull'istruzione Select di SQL


144

Come restituire un valore booleano sull'istruzione Select SQL?

Ho provato questo codice:

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

E ritorna solo TRUEse UserIDesiste sul tavolo. Voglio che ritorni FALSEse UserIDnon esiste sul tavolo.


3
Quale dbms? I dettagli di sql differiscono.
joshp,

SQL Server non supporta un tipo booleano, ad es. SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- genera un errore, ovvero CAST(1 AS BIT)non è lo stesso VERO logico.
giorno

Risposte:


253

Quello che hai lì non restituirà alcuna riga se l'utente non esiste. Ecco cosa ti serve:

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

2
perché usi l'asterisco, è meglio se usi 1invece di *.

7
@ robertpeter07 - I due sono equivalenti, ma *è più idiomatico. Vedere questa domanda .
Chad,

Se usando un ciclo WHILE dovrei racchiuderlo tra parentesi graffe {} subito dopo "WHILE"?
full_prog_full

Puoi aggiungere un nome di colonna al valore restituito?
xMetalDetectorx

3
@xMetalDetectorx Questo ha funzionato per me per aggiungere il nome della colonna (la AS boolparte è molto importante):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo

31

Forse qualcosa del genere:

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
Questo restituisce una stringa, non un booleano
OMG Ponies

È buona norma includere il nome di una colonna: SELEZIONA CAST (CASO QUANDO CONTEGGIO (*)> 0 POI 1 ALTRO 0 FINE COME MORSO) come mycolumnname DAL manichino DOVE id = 1
Diego Alves,

22

Dato che comunemente 1 = truee 0 = false, tutto ciò che devi fare è contare il numero di righe e eseguire il cast su a boolean.

Quindi, il tuo codice pubblicato necessita solo di una COUNT()funzione aggiunta:

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

8
L'esecuzione del Exists(test è molto più rapida rispetto all'esecuzione di un Count(1)test su tabelle con un numero elevato di righe.
Scott Chamberlain,

5
Probabilmente. Nella mia risposta non ho rivendicato prestazioni, ma solo la minima modifica del codice per ottenere ciò che l'OP voleva. Tuttavia, se la colonna UserIDè indicizzata (o è anche il PK) sicuramente andrai direttamente all'unica riga univoca esistente (o meno).
Stewart,

9

Utilizzare 'Esiste' che restituisce 0 o 1.

La query sarà come:

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

10
Errore: "Sintassi errata vicino alla parola chiave" EXISTS "." sqlfiddle.com/#!18/ef905/18
JoePC

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

Se count (*) = 0 restituisce false. Se count (*)> 0 restituisce true.


4

Lo faccio così:

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

Visto che un booleano non può mai essere nullo (almeno in .NET), dovrebbe essere predefinito su falso o puoi impostarlo su quello te stesso se è default come vero. Tuttavia 1 = vero, quindi null = falso e nessuna sintassi aggiuntiva.

Nota: uso Dapper come micro orm, immagino che ADO dovrebbe funzionare allo stesso modo.


La mia risposta preferita e più concisa finora. Fiddle di tutte le risposte: sqlfiddle.com/#!18/ef905/18
JoePC

"Vedere come un booleano non può mai essere nullo (almeno in .NET)." (bool?) è un bool nulla.
Andrew Dennison,

1

Si noti un altro problema equivalente: la creazione di una query SQL che restituisce (1) se la condizione è soddisfatta e un risultato vuoto in caso contrario. Si noti che una soluzione a questo problema è più generale e può essere facilmente utilizzata con le risposte di cui sopra per ottenere la domanda posta. Poiché questo problema è più generale, sto dimostrando la sua soluzione in aggiunta alle meravigliose soluzioni presentate sopra al tuo problema.

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

1

Per quelli di voi che sono interessati a ottenere il valore aggiungendo un nome di colonna personalizzato, questo ha funzionato per me:

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

Puoi saltare le doppie virgolette dal nome della colonna nel caso in cui non ti interessi mantenere la distinzione tra maiuscole e minuscole del nome (in alcuni client).

Ho leggermente modificato la risposta di Chad per questo.


Messaggio 102, livello 15, stato 1, riga 8 Sintassi errata vicino a "CAST". Messaggio 156, livello 15, stato 1, riga 12 Sintassi errata vicino alla parola chiave "THEN".
ShaneC,

@ShaneC Ho testato questo codice su PostgreSQL 9.X e ha funzionato bene. Quale server stai usando?
Lucio Mollinedo,

0
DECLARE @isAvailable      BIT = 0;

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

inizialmente è Il valore booleano disponibile è impostato su 0

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.