EXISTSをビットとして直接選択することは可能ですか?


186

私はこのようなことをすることが可能かどうか疑問に思っていました(これは機能しません):

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

それは実行可能であるように見えますが、SQLで機能するはずの多くのことはできません;)私はこれの回避策を見ました(SELECT 1 where ... Exists ...)が、私はちょうどできるように思えますexists関数の結果をビットとしてキャストし、それで完了します。

回答:


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 2013

3
このテクニックをテストしたところ、うまくいきました。SQL Server 2008 R2でテストされたクエリから結果を取得するために、BITへのCASTは必要ありません。
Tore Aurstad 2015年

私の場合は、キャストを除去する必要がなかった
セルジオS.フィリオ

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

ビットにキャストすると

  • 0-> 0
  • 他のすべて-> 1
  • そしてもちろんNULL-> NULLですが、GROUP BYなしでCOUNT(*)を使用してNULLを取得することはできません

bitboolean.netデータ型に直接マップします。実際にはそうではありません...

これは同じように見えますが、一致しない場合、行はありません(ゼロではありません)ため、同じではありません。

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

4
しかし、これはEXISTSをまったく使用しません。私はそれを回避する方法を尋ねていませんでした、私は回避策を見つけることができます、私が知らないビットとして存在することを使用するいくつかのトリックがあるかどうか尋ねていました。
jcollum

6
これは回避策ではなく、セットごとの正しい方法の1つです。EXISTSはこの回避策です。
-gbn

1
@jcollum:はい、またはこのようなもの。EXISTSはほとんどの場合IF EXISTSまたはWHERE EXISTSであり、実行しようとしているような出力には使用されません
gbn

14
レコードの存在を確認する場合、EXISTSはCOUNTよりも効率的です-sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/…を
Tahir Hassan

9
とは異なりEXISTSCOUNTカウントを取得する必要があるため、最初の行を見つけた後でも、一致する行のデータを探し続けます。
IsmailS 2014年

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ではなくnull(レコードなし)が返されます。


2

いいえ、それは不可能です。ビットデータ型はブールデータ型ではありません。これは、0、1、またはNULLの整数データ型です。


3
@bzlmはい、SQLServerで10年以上使用できます。SQL Server 7.0はそれをmsdn.microsoft.com/en-us/library/aa237157%28SQL.80%29.aspx
Martin Smith

4
@bzlm-わらをつかんでいて、SQL Serverのデータ型について何も知らないようです。SQL Serverでのビットの定義は、「1、0、またはNULLの値を取ることができる整数データ型」です。msdn.microsoft.com/en-us/library/ms177603.aspx。これは、列とTransact SQL変数に適用されます。IF(@TRUE)たとえば、SQLでビット変数をブール値として使用したり、その逆を行ったりして、ブール式をビットに強制変換することはできません。(例: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

私はexistsは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

selectのcase whenはどうですか?
ロワーキー2013

-1
SELECT IIF(EXISTS(SELECT * FROM theTable WHERE theColumn LIKE 'theValue%'), 1, 0)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.