чи можна обрати EXISTS безпосередньо як біт?


186

Мені було цікаво, чи можна зробити щось подібне (яке не працює):

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

Здається, це повинно бути виконано, але багато речей, які повинні працювати в SQL, не роблять; киньте результат існуючої функції як біт і виконайте з нею.

Відповіді:


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
Вам не потрібна трансляція, якщо ви зберігаєте результат у типі даних Bit, тому що команда вже неявна.
MikeTeeVee

3
Щойно перевірена ця методика, чудово працює. CAST to BIT не потрібен для отримання результатів запиту, перевіреного на SQL Server 2008 R2.
Tore Aurstad

У моєму випадку акторський склад ОБОВ'ЯЗКОВО зняти
Серхіо С. Філью

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
Це не обхідне рішення, це єдиний правильний спосіб. Є таке рішення ... І дуже чисто, ні?
gbn

1
@jcollum: так, або щось подібне. EXISTS майже завжди
АКОГО Є ІНШИХ ІДО, І ЩО Є,

14
EXISTS є більш ефективним, ніж COUNT, коли перевіряють наявність запису - див. Sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/…
Тахір Хассан

9
На відміну від цього EXISTS, COUNTбуде продовжувати шукати дані для відповідності рядків навіть після того , як знайде перший, тому що його потрібно отримати підрахунок.
ІсмаїлС

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', це поверне нулеве (без записів), а не трохи 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

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

Як що до цього:

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.