Zwróć wartość logiczną w instrukcji SQL Select

144

Jak zwrócić wartość logiczną w instrukcji SQL Select?

Wypróbowałem ten kod:

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

I powraca tylko TRUEwtedy, gdy UserIDistnieje na stole. Chcę, żeby wrócił, FALSEjeśli UserIDnie ma go na stole.

mrjimoy_05
źródło
3
Które dbms? Szczegóły sql różnią się.
joshp
SQL Server nie obsługuje typu boolowskiego, np. SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- powoduje błąd, tj. CAST(1 AS BIT)Nie jest tą samą logiczną PRAWDA.
onedaywhen

Odpowiedzi:

253

To, co tam masz, nie zwróci żadnego wiersza, jeśli użytkownik nie istnieje. Oto, czego potrzebujesz:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
Czad
źródło
2
po co używać gwiazdki, lepiej jest użyć 1zamiast *.
7
@ robertpeter07 - Te dwa są równoważne, ale *jest bardziej idiomatyczne. Zobacz to pytanie .
Czad
Gdybym używał pętli WHILE, czy musiałbym umieścić ją w nawiasach klamrowych {} tuż po „WHILE”?
full_prog_full
Czy możesz dodać nazwę kolumny do zwracanej wartości?
xMetalDetectorx
3
@xMetalDetectorx Pomogło mi to w dodaniu nazwy kolumny ( AS boolczęść jest bardzo ważna):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo
31

Prawdopodobnie coś w tym stylu:

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

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

obciążenie kablowe
źródło
6
Zwraca ciąg znaków, a nie wartość logiczną
OMG Ponies
Dobrą praktyką jest dołączenie nazwy kolumny - SELECT CAST (CASE WHEN COUNT (*)> 0 THEN 1 ELSE 0 END AS BIT) jako nazwa mojej kolumny FROM dummy WHERE id = 1
Diego Alves
22

Biorąc pod uwagę, że często 1 = truei 0 = falsewszystko, co musisz zrobić, to policzyć liczbę wierszy i rzucić na boolean.

Dlatego Twój opublikowany kod wymaga tylko COUNT()dodania funkcji:

SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)
Stewart
źródło
8
Wykonanie Exists(testu jest znacznie szybsze niż wykonanie Count(1)testu na tabelach z dużą liczbą wierszy.
Scott Chamberlain
5
Prawdopodobnie. W mojej odpowiedzi nie twierdziłem, że chodzi o wydajność, tylko minimalna zmiana kodu, aby osiągnąć to, czego chciał OP. Jeśli jednak kolumna UserIDjest zindeksowana (lub nawet jest PK), z pewnością przechodzisz bezpośrednio do jedynego unikalnego wiersza, który istnieje (lub nie).
Stewart
9

Użyj „Exists”, który zwraca 0 lub 1.

Zapytanie będzie wyglądać następująco:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)
Ananthi
źródło
10
Błąd: „Nieprawidłowa składnia w pobliżu słowa kluczowego„ ISTNIEJE ””. sqlfiddle.com/#!18/ef905/18
JoePC,
8
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

Jeśli count (*) = 0 zwraca false. Jeśli count (*)> 0 zwraca prawdę.

G.Noulas
źródło
4

Robię to tak:

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

Widząc, że boolean nigdy nie może być zerowy (przynajmniej w .NET), powinien domyślnie mieć wartość false lub możesz ustawić go samodzielnie, jeśli domyślnie jest prawdziwy. Jednak 1 = prawda, więc null = fałsz i bez dodatkowej składni.

Uwaga: używam Dappera jako mojego mikro orma, wyobrażam sobie, że ADO powinno działać tak samo.

RandomUs1r
źródło
Moja ulubiona, jak dotąd najbardziej zwięzła odpowiedź. Skrzypce
JoePC
„Postrzeganie jako wartości logicznej nigdy nie może być zerowe (przynajmniej w .NET)”. (bool?) jest wartością zerową bool.
Andrew Dennison,
1

Zwróć uwagę na inny równoważny problem: Tworzenie zapytania SQL, które zwraca (1), jeśli warunek jest spełniony, a pusty wynik w przeciwnym razie. Zauważ, że rozwiązanie tego problemu jest bardziej ogólne i można je łatwo zastosować z powyższymi odpowiedziami, aby uzyskać zadane pytanie. Ponieważ ten problem jest bardziej ogólny, oprócz pięknych rozwiązań przedstawionych powyżej udowadniam jego rozwiązanie.

SELECT DISTINCT 1 AS Expr1
FROM [User]
WHERE (UserID = 20070022)
Dean Leitersdorf
źródło
1

Dla tych z Was, którzy są zainteresowani uzyskaniem wartości dodanej niestandardowej nazwy kolumny, zadziałało to:

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

Możesz pominąć podwójne cudzysłowy w nazwie kolumny na wypadek, gdybyś nie był zainteresowany zachowywaniem wielkości liter w nazwie (w niektórych klientach).

Nieznacznie poprawiłem odpowiedź @ Chad na to.

Lucio Mollinedo
źródło
Msg 102, poziom 15, stan 1, wiersz 8 Niepoprawna składnia w pobliżu „CAST”. Msg 156, poziom 15, stan 1, wiersz 12 Niepoprawna składnia w pobliżu słowa kluczowego „THEN”.
ShaneC
@ShaneC Przetestowałem ten kod na PostgreSQL 9.X i działał dobrze. Z jakiego serwera korzystasz?
Lucio Mollinedo
0
DECLARE @isAvailable      BIT = 0;

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

początkowo wartość logiczna isAvailable jest ustawiona na 0

Chamin Thilakarathne
źródło