Valor booleano de retorno na instrução SQL Select

144

Como retornar um valor booleano na instrução SQL Select?

Eu tentei este código:

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

E ele só retorna TRUEse UserIDexistir na mesa. Quero que ele retorne FALSEse UserIDnão existir na mesa.

mrjimoy_05
fonte
3
Quais dbms? Os detalhes do sql diferem.
joshp
O SQL Server não oferece suporte a um tipo booleano, por exemplo SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- resulta em um erro, ou CAST(1 AS BIT)seja, não é o mesmo VERDADEIRO lógico.
usar o seguinte código

Respostas:

253

O que você tem lá não retornará nenhuma linha se o usuário não existir. Aqui está o que você precisa:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
Chade
fonte
2
por que usar o asterisco, é melhor se você usar em 1vez de *.
7
@ robertpeter07 - Os dois são equivalentes, mas *são mais idiomáticos. Veja esta pergunta .
Chad
Se usar um loop WHILE, eu teria que colocá-lo entre chaves {} logo após o 'WHILE'?
full_prog_full
Você pode adicionar um nome de coluna ao valor retornado?
XMetalDetectorx
3
@xMetalDetectorx Isso funcionou para eu adicionar o nome da coluna (a AS boolparte é muito importante):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo 29/11
31

Possivelmente algo nesse 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

cableload
fonte
6
Isso retorna uma string, não um boolean
OMG Pôneis
É uma boa prática incluir um nome de coluna - 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, geralmente , 1 = truee 0 = falsetudo o que você precisa fazer é contar o número de linhas e converter para umboolean .

Portanto, seu código publicado precisa apenas de uma COUNT()função adicionada:

SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)
Stewart
fonte
8
Fazer o Exists(teste é muito mais rápido do que fazer um Count(1)teste em tabelas com grande número de linhas.
21414 Scott Scott
5
Provavelmente. Não fiz reivindicações de desempenho em minha resposta, apenas a alteração mínima do código para alcançar o que o OP queria. No entanto, se a coluna UserIDestiver indexada (ou é mesmo a PK), certamente você estará indo diretamente para a única linha que existe (ou não).
Stewart
9

Use 'Exists', que retorna 0 ou 1.

A consulta será como:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)
Ananthi
fonte
10
Erro: "Sintaxe incorreta perto da palavra-chave 'EXISTS'." sqlfiddle.com/#!18/ef905/18
JoePC
8
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

Se count (*) = 0 retorna false. Se count (*)> 0 retornar verdadeiro.

G.Noulas
fonte
4

Eu faço assim:

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

Visto que um booleano nunca pode ser nulo (pelo menos no .NET), ele deve ser padronizado como false ou você pode configurá-lo como esse se for o padrão true. No entanto, 1 = verdadeiro, então nulo = falso e sem sintaxe extra.

Nota: Eu uso o Dapper como minha micro orm, eu imagino que o ADO funcione da mesma forma.

RandomUs1r
fonte
Minha resposta mais concisa e favorita até agora. Violino de todas as respostas: sqlfiddle.com/#!18/ef905/18
JoePC
"Ver como um booleano nunca pode ser nulo (pelo menos no .NET)." (bool?) é um bool anulável.
Andrew Dennison
1

Observe outro problema equivalente: Criando uma consulta SQL que retorne (1) se a condição for atendida e um resultado vazio caso contrário. Observe que uma solução para esse problema é mais geral e pode ser facilmente usada com as respostas acima para obter a pergunta que você fez. Como esse problema é mais geral, estou provando sua solução, além das belas soluções apresentadas acima para o seu problema.

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

Para aqueles que estão interessados ​​em obter o valor adicionando um nome de coluna personalizado, isso funcionou para mim:

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

Você pode pular as aspas duplas do nome da coluna caso não esteja interessado em manter a distinção entre maiúsculas e minúsculas do nome (em alguns clientes).

Ajustei levemente a resposta de @ Chad para isso.

Lucio Mollinedo
fonte
Msg 102, Nível 15, Estado 1, Linha 8 Sintaxe incorreta perto de 'CAST'. Msg 156, Nível 15, Estado 1, Linha 12 Sintaxe incorreta perto da palavra-chave 'THEN'.
ShaneC 26/06
@ShaneC Eu testei esse código no PostgreSQL 9.X e funcionou bem. Qual servidor você está usando?
Lucio Mollinedo 29/06
0
DECLARE @isAvailable      BIT = 0;

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

O valor booleano inicialmente isAvailable é definido como 0

Chamin Thilakarathne
fonte