Devolver valor booleano en la instrucción de selección SQL

144

¿Cómo devolver un valor booleano en la instrucción de selección SQL?

Probé este código:

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

Y solo regresa TRUEsi UserIDexiste en la tabla. Quiero que regrese FALSEsi UserIDno existe en la tabla.

mrjimoy_05
fuente
3
¿Qué dbms? Los detalles de sql difieren.
joshp
SQL Server no admite un tipo booleano, por ejemplo SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result, da como resultado un error, CAST(1 AS BIT)es decir, no es el mismo VERDADERO lógico.
cuando el

Respuestas:

253

Lo que tenga allí no devolverá ninguna fila si el usuario no existe. Esto es lo que necesitas:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
Chad
fuente
2
por qué usar asterisco, es mejor si lo usa en 1lugar de *.
77
@ robertpeter07 - Los dos son equivalentes, pero *son más idiomáticos. Ver esta pregunta .
Chad
Si lo uso en un ciclo WHILE, ¿tendría que encerrarlo entre llaves {} justo después de 'WHILE'?
full_prog_full
¿Se puede agregar un nombre de columna al valor devuelto?
xMetalDetectorx
3
@xMetalDetectorx Esto funcionó para mí para agregar el nombre de la columna (la AS boolparte es muy importante):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo
31

Posiblemente algo en este sentido:

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

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

carga de cable
fuente
66
Esto devuelve una cadena, no un booleano
OMG Ponies
Es una buena práctica incluir un nombre de columna: SELECT CAST (CASE WHEN COUNT (*)> 0 THEN 1 ELSE 0 END AS BIT) como mycolumnname FROM dummy WHERE id = 1
Diego Alves
22

Dado que comúnmente 1 = truey 0 = false, todo lo que necesita hacer es contar el número de filas y emitir a boolean.

Por lo tanto, su código publicado solo necesita una COUNT()función agregada:

SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)
Stewart
fuente
8
Hacer la Exists(prueba es mucho más rápido que hacer una Count(1)prueba en tablas con un gran número de filas.
Scott Chamberlain
55
Probablemente. No respondí al rendimiento en mi respuesta, solo el mínimo cambio de código para lograr lo que quería el OP. Sin embargo, si la columna UserIDestá indexada (o incluso es la PK) seguramente irá directamente a la única fila que existe (o no).
Stewart
9

Use 'Existe' que devuelve 0 o 1.

La consulta será como:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)
Ananthi
fuente
10
Error: "Sintaxis incorrecta cerca de la palabra clave 'EXISTE'". sqlfiddle.com/#!18/ef905/18
JoePC
8
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

Si count (*) = 0 devuelve falso. Si count (*)> 0 devuelve verdadero.

G.Noulas
fuente
4

Lo hago así:

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

Al ver que un booleano nunca puede ser nulo (al menos en .NET), debería ser falso por defecto o puede configurarlo usted mismo si su valor predeterminado es verdadero. Sin embargo, 1 = verdadero, entonces nulo = falso, y sin sintaxis adicional.

Nota: Yo uso Dapper como mi micro ormo, imagino que ADO debería funcionar igual.

RandomUs1r
fuente
Mi respuesta favorita y más concisa hasta ahora. Violín de todas las respuestas: sqlfiddle.com/#!18/ef905/18
JoePC
"Verlo como un booleano nunca puede ser nulo (al menos en .NET)". (bool?) es un bool anulable.
Andrew Dennison
1

Observe otro problema equivalente: crear una consulta SQL que devuelva (1) si se cumple la condición y un resultado vacío de lo contrario. Tenga en cuenta que una solución a este problema es más general y se puede usar fácilmente con las respuestas anteriores para lograr la pregunta que hizo. Como este problema es más general, estoy probando su solución además de las hermosas soluciones presentadas anteriormente para su problema.

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

Para aquellos de ustedes que están interesados ​​en obtener el valor agregando un nombre de columna personalizado, esto funcionó para mí:

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

Puede omitir las comillas dobles del nombre de la columna en caso de que no esté interesado en mantener la distinción entre mayúsculas y minúsculas del nombre (en algunos clientes).

Ajusté ligeramente la respuesta de @ Chad para esto.

Lucio Mollinedo
fuente
Mensaje 102, Nivel 15, Estado 1, Línea 8 Sintaxis incorrecta cerca de 'CAST'. Mensaje 156, Nivel 15, Estado 1, Línea 12 Sintaxis incorrecta cerca de la palabra clave 'ENTONCES'.
ShaneC
@ShaneC Probé este código en PostgreSQL 9.X y funcionó bien. ¿Qué servidor estás usando?
Lucio Mollinedo
0
DECLARE @isAvailable      BIT = 0;

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

inicialmente isAvailable el valor booleano se establece en 0

Chamin Thilakarathne
fuente