MIN集計関数をBITフィールドに適用する


82

次のクエリを書きたい:

SELECT   ..., MIN(SomeBitField), ...
FROM     ...
WHERE    ...
GROUP BY ...

問題は、SQL Serverがそれを好まないことですOperand data type bit is invalid for min operatorビットフィールドの最小値を計算したい場合、エラーが返されます。

次の回避策を使用できます。

SELECT   ..., CAST(MIN(CAST(SomeBitField AS INT)) AS BIT), ...
FROM     ...
WHERE    ...
GROUP BY ...

しかし、もっとエレガントなものはありますか?(たとえば、私が知らないand、フィールド内のビット値の論理を評価する集計関数がある場合があります。)


2
@アダムロビンソン:明らかに、Operand data type bit is invalid for min operator.
アンドマール2011

4
よりエレガントなことはわかりませんが、少し短いです。cast(min(SomeBitField+0) as bit)
Mikael Eriksson

5
@Andomar:もちろん、すでに問題を知っている場合はそうですが、同様の問題を抱えている他の人がエラーメッセージを検索する可能性があるため、そのような情報を質問に含める必要があります。
アダムロビンソン

回答:


33

のオプションは2つしかないBITため、caseステートメントを使用してください。

SELECT CASE WHEN EXISTS (SELECT 1 FROM ....) THEN 1 ELSE 0 END AS 'MinBit'
FROM ...
WHERE ...

これには次の利点があります。

  • テーブルスキャンを強制しない(BITフィールドのインデックスはほとんど使用されません)
  • TWICEの短絡(1回EXISTSと2回CASE

書くのはもう少しコードですが、ひどいことではありません。確認する値が複数ある場合は、クエリの開始時に、より大きな結果セット(JOINおよびすべてのFILTER条件を含む)を常にカプセル化CTEして、CASEステートメントでそれを参照できます。


10
bitnull許容型であるかどうかについては、3つのオプションがあります。
マーティンスミス

1
bit列が完全にNULL値で構成されている場合は、MINを返す必要がありますNULL
マーティンスミス

8
私は「より少ない」プログラマーでなければなりませんが、select 1 from ...サブクエリの完全な例を見たかったのです。それはまったく意味がありません。
Vaccano 2012年

2
@Vaccano -SELECT 1 FROM Outertable WHERE bitfield=1
JNK

2
ただし、元の質問にはGROUPBYが含まれていました。WHEREにgroupby基準を含める必要があります。
Tmdean 2015年

156

1つのオプションはMIN(SomeBitField+0)です。ノイズが少なく、読みやすくなっています(これはエレガンスと見なされます)。

とは言うものの、それはCASEオプションよりもハックっぽいです。そして、私は速度/効率について何も知りません。


@ベン、どうもありがとう、これも私のSQLクエリに役立ちます。
PatsonLeaner 2018年

@ベン、+ 0のドキュメントはありますか?、それを探しようとしましたが、参照のために何も見つかりませんでした:)
FranciscoSevilla20年

1
@FranciscoSevilla私はそれがあるため、暗黙的な優先順位変換のだと信じて:docs.microsoft.com/en-us/sql/t-sql/data-types/...
ベン・モッシャー

7

このクエリが最適なソリューションです。

SELECT CASE WHEN MIN(BitField+0) = 1 THEN 'True' ELSE 'False' END AS MyColumn
 FROM MyTable

BitField + 0を追加すると、自動的にintのようになります。



6

次の注を試して ください:最小表現および集計関数、最大表現または集計関数

SELECT   ..., MIN(case when SomeBitField=1 then 1 else 0 end), MIN(SomeBitField+0)...
FROM     ...
WHERE    ...
GROUP BY ...

同じ結果


5

この小さなコードは、常に魅力のように機能してきました。

CONVERT(BIT, MIN(CONVERT(INT, BitField))) as BitField

2

AVG(CAST(boolean_column AS FLOAT))OVER(...)AS BOOLEAN_AGGREGATE

ファジーブール値を与える:

  • 1はそれがすべて正しいことを示します。

  • 0はそれがすべて偽であることを示します。

  • ] 0..1 [の間の値は部分一致を示し、真実のパーセンテージになる可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.