Booleschen Wert in SQL Select-Anweisung zurückgeben


144

Wie kann ein boolescher Wert in der SQL Select-Anweisung zurückgegeben werden?

Ich habe diesen Code ausprobiert:

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

Und es wird nur zurückgegeben, TRUEwenn das UserIDauf dem Tisch vorhanden ist. Ich möchte, dass es zurückkehrt, FALSEwenn das UserIDnicht auf dem Tisch existiert.


3
Welche dbms? Details von SQL unterscheiden sich.
Joshp

SQL Server unterstützt keinen Booleschen Typ, z. B. SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- führt zu einem Fehler, dh es CAST(1 AS BIT)ist nicht dieselbe logische WAHR.
Tag, wenn

Antworten:


253

Was Sie dort haben, gibt überhaupt keine Zeile zurück, wenn der Benutzer nicht existiert. Folgendes benötigen Sie:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END

2
Warum Sternchen verwenden, ist es besser, wenn Sie 1anstelle von verwenden *.

7
@ robertpeter07 - Die beiden sind gleichwertig, aber *idiomatischer. Siehe diese Frage .
Chad

Wenn ich eine WHILE-Schleife verwenden würde, müsste ich sie direkt nach dem 'WHILE' in geschweifte Klammern {} setzen?
full_prog_full

Können Sie dem zurückgegebenen Wert einen Spaltennamen hinzufügen?
xMetalDetectorx

3
@xMetalDetectorx Dies funktionierte für mich, um den Spaltennamen hinzuzufügen (der AS boolTeil ist sehr wichtig):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo

31

Möglicherweise etwas in diese Richtung:

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

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


6
Dies gibt eine Zeichenfolge zurück, keine boolesche
OMG Ponies

Es ist eine gute Praxis, einen Spaltennamen - SELECT CAST (CASE WHEN COUNT (*)> 0 THEN 1 ELSE 0 END AS BIT) als mycolumnname FROM Dummy WHERE id = 1
Diego Alves

22

Da häufig 1 = trueund 0 = falsealles, was Sie tun müssen , ist die Anzahl der Zeilen zu zählen, und Umwandlung in einem boolean.

Daher muss für Ihren gebuchten Code nur eine COUNT()Funktion hinzugefügt werden:

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

8
Der Exists(Test ist viel schneller als ein Count(1)Test für Tabellen mit einer großen Anzahl von Zeilen.
Scott Chamberlain

5
Wahrscheinlich. Ich habe in meiner Antwort keine Leistungsansprüche geltend gemacht, nur die minimale Codeänderung, um das zu erreichen, was das OP wollte. Wenn die Spalte UserIDjedoch indiziert ist (oder sogar die PK ist), gelangen Sie sicher direkt zu der einen eindeutigen Zeile, die vorhanden ist (oder nicht).
Stewart

9

Verwenden Sie 'Exists', das entweder 0 oder 1 zurückgibt.

Die Abfrage lautet wie folgt:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)

10
Fehler: "Falsche Syntax in der Nähe des Schlüsselworts 'EXISTS'." sqlfiddle.com/#!18/ef905/18
JoePC

8
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

Wenn count (*) = 0 ist, wird false zurückgegeben. Wenn count (*)> 0 ist, wird true zurückgegeben.


4

So mach ich es:

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

Da ein Boolescher Wert niemals null sein kann (zumindest in .NET), sollte er standardmäßig false sein, oder Sie können ihn selbst festlegen, wenn er standardmäßig true ist. Jedoch 1 = wahr, also null = falsch und keine zusätzliche Syntax.

Hinweis: Ich verwende Dapper als Mikro-Orm. Ich würde mir vorstellen, dass ADO genauso funktionieren sollte.


Meine bisher beliebteste und prägnanteste Antwort. Geige aller Antworten: sqlfiddle.com/#!18/ef905/18
JoePC

"Als Boolescher Wert zu sehen, kann niemals null sein (zumindest in .NET)." (bool?) ist ein nullbarer Bool.
Andrew Dennison

1

Beachten Sie ein weiteres gleichwertiges Problem: Erstellen einer SQL-Abfrage, die (1) zurückgibt, wenn die Bedingung erfüllt ist, und ansonsten ein leeres Ergebnis. Beachten Sie, dass eine Lösung für dieses Problem allgemeiner ist und mit den obigen Antworten leicht verwendet werden kann, um die von Ihnen gestellte Frage zu beantworten. Da dieses Problem allgemeiner ist, beweise ich seine Lösung zusätzlich zu den schönen Lösungen, die oben für Ihr Problem vorgestellt wurden.

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

1

Für diejenigen unter Ihnen, die daran interessiert sind, den Wert eines benutzerdefinierten Spaltennamens hinzuzufügen, hat dies für mich funktioniert:

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

Sie können die doppelten Anführungszeichen aus dem Spaltennamen überspringen, falls Sie nicht daran interessiert sind, die Groß- und Kleinschreibung des Namens beizubehalten (bei einigen Clients).

Ich habe die Antwort von @ Chad darauf leicht angepasst.


Meldung 102, Ebene 15, Status 1, Zeile 8 Falsche Syntax in der Nähe von 'CAST'. Meldung 156, Ebene 15, Status 1, Zeile 12 Falsche Syntax in der Nähe des Schlüsselworts 'THEN'.
ShaneC

@ShaneC Ich habe diesen Code auf PostgreSQL 9.X getestet und es hat gut funktioniert. Welchen Server verwenden Sie?
Lucio Mollinedo

0
DECLARE @isAvailable      BIT = 0;

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

anfangs ist der boolesche Wert isAvailable auf 0 gesetzt

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.