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.


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

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


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)

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)

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ę.


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.


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)

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.


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.