Можно ли выбрать EXISTS напрямую как бит?


186

Мне было интересно, если это возможно сделать что-то вроде этого (что не работает):

select cast( (exists(select * from theTable where theColumn like 'theValue%') as bit)

Похоже, это должно быть выполнимо, но многие вещи, которые должны работать в SQL, не работают;) Я видел обходные пути для этого (SELECT 1, где ... существует ...), но кажется, что я должен просто приведите результат функции существует как бит и покончите с этим.

Ответы:


267

Нет, вам придется использовать обходной путь.

Если вы должны вернуть условный бит 0/1, другой способ:

SELECT CAST(
   CASE WHEN EXISTS(SELECT * FROM theTable where theColumn like 'theValue%') THEN 1 
   ELSE 0 
   END 
AS BIT)

Или без актерского состава:

SELECT
   CASE
       WHEN EXISTS( SELECT 1 FROM theTable WHERE theColumn LIKE 'theValue%' )
            THEN 1 
       ELSE 0 
   END

16
Вам не нужно приведение, если вы сохраняете результат в битовом типе данных, потому что приведение уже неявно.
MikeTeeVee

3
Только что опробовал эту технику, прекрасно работает. CAST to BIT не требуется для получения результатов запроса, протестированного с SQL Server 2008 R2.
Торе Аурстад

В моем случае актерский состав ДОЛЖЕН быть удален
Sérgio S. Filho

51
SELECT CAST(COUNT(*) AS bit) FROM MyTable WHERE theColumn like 'theValue%'

Когда вы бросаете в бит

  • 0 -> 0
  • все остальное -> 1
  • И NULL -> NULL, конечно, но вы не можете получить NULL с COUNT (*) без GROUP BY

bitсопоставляется непосредственно с booleanтипами данных .net, даже если это не совсем так ...

Это выглядит похоже, но не дает строки (не ноль), если нет совпадений, так что это не то же самое

SELECT TOP 1 CAST(NumberKeyCOlumn AS bit) FROM MyTable WHERE theColumn like 'theValue%'

4
Но это не использует EXISTS вообще. Я не спрашивал, как обойти это, я мог найти обходные пути, я спрашивал, есть ли какая-то хитрость в использовании существует как бит, о котором я не знал.
jcollum

6
Это не обходной путь, это один правильный способ установки. СУЩЕСТВУЕТ ли это обходной путь ... И очень чистый, нет?
2010 года

1
@jcollum: да, или как-то так. EXISTS почти всегда, если EXISTS или WHERE EXISTS, и не используется для вывода, как вы пытаетесь сделать
gbn

14
EXISTS более эффективен, чем COUNT, при проверке существования записи - см. Sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/…
Тахир Хассан,

9
В отличие от этого EXISTS, COUNTбудет продолжать искать данные на предмет соответствия строк даже после нахождения первой, потому что для этого нужно получить счетчик.
IsmailS

11

Я немного опаздываю на это; просто наткнулся на пост. Однако вот решение, которое является более эффективным и аккуратным, чем выбранный ответ, но должно предоставлять такую ​​же функциональность:

declare @t table (name nvarchar(16))
declare @b bit

insert @t select N'Simon Byorg' union select N'Roe Bott'


select @b = isnull((select top 1 1 from @t where name = N'Simon Byorg'),0)
select @b whenTrue

select @b = isnull((select top 1 1 from @t where name = N'Anne Droid'),0)
select @b whenFalse

7

Вы можете использовать IIFиCAST

SELECT CAST(IIF(EXISTS(SELECT * FROM theTable 
                       where theColumn like 'theValue%'), 1, 0) AS BIT)

1
Мне это нравится, но это работает только в SQL Server 2012 и выше. Похоже, IIF был добавлен в 2012 году
ja928

5

Вы также можете сделать следующее:

SELECT DISTINCT 1
  FROM theTable
 WHERE theColumn LIKE 'theValue%'

Если нет значений, начинающихся с 'theValue', это вернет null (без записей), а не бит 0, хотя


2

Нет, это невозможно. Битовый тип данных не является логическим типом данных. Это целочисленный тип данных, который может быть 0,1 или NULL.


3
@bzlm Да, это возможно в SQLServer более 10 лет. SQL Server 7.0 представил его msdn.microsoft.com/en-us/library/aa237157%28SQL.80%29.aspx
Мартин Смит

4
@bzlm - Похоже, вы цепляетесь за соломинку и ничего не знаете о типах данных SQL Server. Определение бита в SQL Server: «Целочисленный тип данных, который может принимать значение 1, 0 или NULL». msdn.microsoft.com/en-us/library/ms177603.aspx . Это относится к столбцам и переменным Transact SQL. Нигде нельзя использовать битовую переменную в качестве логического значения в SQL, IF(@TRUE)например, и наоборот, логическое выражение не может быть приведено к битам. (Например SET @BitVariable = (1=1))
Мартин Смит

1
Я понимаю, куда вы идете, но приведение к бите было не столько проблемой, сколько возможностью напрямую выбрать EXISTS.
Jcollum

1

Другое решение заключается в использовании ISNULLв тандеме с SELECT TOP 1 1:

SELECT ISNULL((SELECT TOP 1 1 FROM theTable where theColumn like 'theValue%'), 0)

-1

Я считаю, что существует можно использовать только в предложении where, поэтому вам придется обойти это решение (или подзапрос с существует в качестве предложения where). Я не знаю, считается ли это обходным решением.

Как насчет этого:

create table table1 (col1   int null)
go
select 'no items',CONVERT(bit, (select COUNT(*) from table1) )   -- returns 'no items', 0
go
insert into table1 (col1) values (1)
go
select '1 item',CONVERT(bit, (select COUNT(*) from table1) )     --returns '1 item', 1
go
insert into table1 (col1) values (2)
go
select '2 items',CONVERT(bit, (select COUNT(*) from table1) )    --returns '2 items', 1
go
insert into table1 (col1) values (3)
go
drop table table1
go

Как насчет случая, когда в выборе?
нижний ключ

-1
SELECT IIF(EXISTS(SELECT * FROM theTable WHERE theColumn LIKE 'theValue%'), 1, 0)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.