Возвращает логическое значение в операторе выбора SQL


144

Как вернуть логическое значение в SQL Select Statement?

Я попробовал этот код:

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

И это только возвращает, TRUEесли UserIDсуществует на столе. Я хочу, чтобы он вернулся, FALSEесли UserIDна столе не существует.


3
Какие дБмс? Детали sql отличаются.
Joshp

SQL Server не поддерживает логический тип, например SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- приводит к ошибке, т. Е. Не CAST(1 AS BIT)является той же логической ИСТИНОЙ.
onedaywhen

Ответы:


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
Лусио Моллинедо

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

Рекомендуется включать имя столбца - SELECT CAST (CASE WHEN COUNT (*)> 0 THEN 1 ELSE 0 END AS BIT) в качестве mycolumnname FROM dummy WHERE id = 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проиндексирован (или даже является PK), вы наверняка идете прямо к единственной существующей строке (или нет).
Стюарт

9

Используйте «Exists», который возвращает 0 или 1.

Запрос будет выглядеть так:

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

10
Ошибка: «Неверный синтаксис рядом с ключевым словом« EXISTS ».» 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 или вы можете установить его на это значение самостоятельно, если значение по умолчанию равно true. Однако 1 = истина, поэтому нуль = ложь, и никакого дополнительного синтаксиса.

Примечание: я использую Dapper в качестве микроорганизма, я думаю, ADO должен работать так же.


Мой любимый, самый краткий ответ до сих пор. Скрипка всех ответов: sqlfiddle.com/#!18/ef905/18
JoePC

«Видение логического значения никогда не может быть нулевым (по крайней мере, в .NET)». (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 Неверный синтаксис рядом с ключевым словом "THEN".
ShaneC

@ShaneC Я тестировал этот код на PostgreSQL 9.X, и он работал нормально. Какой сервер вы используете?
Лусио Моллинедо

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.