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.