Повернути бульне значення у виписці SQL Select


144

Як повернути бульне значення в операторі вибору SQL?

Я спробував цей код:

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

І повертається лише в тому TRUEвипадку, якщо UserIDіснує на столі. Я хочу, щоб він повернувся, FALSEякщо його UserIDнемає на столі.


3
Які dbms? Деталі sql відрізняються.
joshp

SQL Server не підтримує булевий тип, наприклад SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- призводить до помилки, тобто CAST(1 AS BIT)не є такою ж логічною TRUE.
день, коли

Відповіді:


253

Що у вас там, взагалі не буде повернено жодного рядка, якщо користувача не існує. Ось що вам потрібно:

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

2
навіщо використовувати зірочку, краще, якщо ви використовуєте 1замість *.

7
@ robertpeter07 - двоє рівнозначних, але *більш ідіоматичні. Дивіться це питання .
Чад

Якщо при використанні циклу WHILE мені доведеться вкласти його в дужки {} відразу після "WHILE"?
full_prog_full

Чи можете ви додати ім'я стовпця до повернутого значення?
xMetalDetectorx

3
@xMetalDetectorx Це допомогло мені додати назву стовпця ( AS boolдеталь дуже важлива):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo

31

Можливо, щось у цьому напрямку:

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
Це повертає рядок, а не булевий
OMG Ponies

Добра практика включати назву стовпця - ВИБІРТИ КАСТ (СЛУЧАЙ, КОЛИ КОНТУРАЛЬ (*)> 0 ТАКІ 1 ЕЛЬЗЕ 0 КІНЦЕ ТАКОЖ БІТ) як своє ім’я стовпця ІЗ манекена, де ІД = 1
Дієго Алвес

22

Враховуючи, що зазвичай 1 = trueі 0 = falseвсе, що вам потрібно зробити, - це підрахувати кількість рядків і віддати до а boolean.

Отже, ваш розміщений код потребує лише COUNT()доданої функції:

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

8
Зробити Exists(тест набагато швидше, ніж робити Count(1)тест на таблицях з великою кількістю рядків.
Скотт Чемберлен

5
Ймовірно. Я не претендував на ефективність у своїй відповіді, лише мінімальна зміна коду, щоб досягти того, чого хотів ОП. Однак якщо стовпець UserIDіндексований (або це навіть ПК), ви безперечно переходите до одного унікального рядка, який існує (чи ні).
Стюарт

9

Використовуйте "Існує", який повертає або 0, або 1.

Запит буде таким:

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

10
Помилка: "Неправильний синтаксис біля ключового слова" ІСНУЄ "." sqlfiddle.com/#!18/ef905/18
JoePC

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

Якщо count (*) = 0 повертає false. Якщо count (*)> 0 повертає true.


4

Я роблю це так:

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

Розглядаючи як булеве, ніколи не може бути нульовим (принаймні, у .NET), воно за замовчуванням має значення false, або ви можете встановити це для себе, якщо це не відповідає дійсності. Однак 1 = true, так null = false, і зайвих синтаксисів немає.

Примітка. Я використовую Dapper як мікроорганізм, я думаю, що ADO повинен працювати так само.


Моя улюблена, найкоротша відповідь поки що. Скрипка всіх відповідей: sqlfiddle.com/#!18/ef905/18
JoePC

"Бачити булевим ніколи не може бути нульовим (принаймні, у .NET)." (bool?) - нульовий bool.
Ендрю Деннісон

1

Зауважте ще одну еквівалентну проблему: Створення SQL-запиту, який повертається (1), якщо умова задоволена, а порожній результат - в іншому випадку. Зауважте, що вирішення цієї проблеми є більш загальним і може бути легко використане з наведеними вище відповідями для досягнення поставленого вами питання. Оскільки ця проблема є більш загальною, я доводжу її рішення на додаток до красивих рішень, представлених вище для вашої проблеми.

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

1

Для тих із вас, хто зацікавлений отримати значення, додавши спеціальну назву стовпця, це працювало для мене:

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

Ви можете пропустити подвійні лапки з імені стовпця, якщо вам не цікаво зберігати чутливість регістру імені (у деяких клієнтів).

Я злегка підробив відповідь на це @ Чад.


Повідомлення 102, рівень 15, стан 1, рядок 8 Неправильний синтаксис біля "CAST". Повідомлення 156, рівень 15, стан 1, рядок 12 Неправильний синтаксис біля ключового слова "ТАМ".
ShaneC

@ShaneC Я перевірив цей код на PostgreSQL 9.X, і він працював чудово. Який сервер ви використовуєте?
Lucio Mollinedo

0
DECLARE @isAvailable      BIT = 0;

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

спочатку isAvailable булеве значення встановлено на 0

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.