MIN toplama işlevini bir BIT alanına uygulama


82

Aşağıdaki sorguyu yazmak istiyorum:

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

Sorun şu ki, SQL Server bundan hoşlanmıyor, bir bit alanının minimum değerini hesaplamak istediğimde hata veriyor Operand data type bit is invalid for min operator.

Aşağıdaki geçici çözümü kullanabilirim:

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

Ama daha zarif bir şey var mı? (Örneğin, bilmediğim ve andbir alandaki bit değerlerinin mantığını değerlendiren bir toplama işlevi olabilir .)


2
@Adam Robinson: Açıkçası,Operand data type bit is invalid for min operator.
Andomar

4
Daha zarif olduğunu bilmiyorum ama biraz daha kısa. cast(min(SomeBitField+0) as bit)
Mikael Eriksson

5
@Andomar: Açıkçası, sorunu zaten biliyorsanız, evet, ancak benzer sorunları olan diğerleri hata mesajında arama yapabilir , bu nedenle soruda bunun gibi bilgilerin olması gerekir.
Adam Robinson

Yanıtlar:


33

İçin yalnızca iki seçenek olduğundan BIT, sadece bir case ifadesi kullanın:

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

Bunun avantajı şu şekildedir:

  • Tablo taramasını zorlamamak ( BITalanlardaki dizinler hemen hemen hiç kullanılmaz)
  • İKİ KEZ kısa devre (bir kez EXISTSve tekrar için CASE)

Yazmak için biraz daha fazla kod ama korkunç olmamalı. Kontrol edilecek birden çok değeriniz varsa, daha büyük sonuç kümenizi (tüm JOINve FILTERölçütleriyle birlikte) her zaman CTEsorgunun başındaki bir a içinde kapsülleyebilir , ardından CASEifadelerde buna başvurabilirsiniz.


10
bitNull yapılabilirse için üç seçenek vardır .
Martin Smith

1
Eğer bitkolon tamamen oluşuyordu NULLdeğerlerine sonra MINdönmelidir NULL.
Martin Smith

8
"Daha az" bir programcı olmalıyım, ancak select 1 from ...alt sorgunun tam bir örneğini görmek isterdim . Pek mantıklı değil.
Vaccano

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

2
Asıl soru bir GROUP BY içeriyordu. Grubu ölçütlere göre WHERE alanına eklemeniz gerekir.
Tmdean

156

Seçeneklerden biri MIN(SomeBitField+0). Daha az gürültüyle iyi okur (zerafet olarak nitelendireceğim).

Bununla birlikte, CASEseçenekten daha hack-ish olduğunu söyledi . Ve hız / verimlilik hakkında hiçbir şey bilmiyorum.


@Ben, Çok teşekkürler, Bu alson SQL Sorgum için bana yardımcı oluyor.
PatsonLeaner

@Ben, +0 ile ilgili bazı belgeleriniz var mı?, Aramaya çalıştım ama hiçbir şey bulamadınız, sadece referanslar için :)
Francisco Sevilla

1
@FranciscoSevilla Bunun örtük öncelik dönüşümünden kaynaklandığına inanıyorum: docs.microsoft.com/en-us/sql/t-sql/data-types/…
Ben Mosher

7

Bu sorgu en iyi çözümdür:

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

BitField + 0'ı eklediğinizde otomatik olarak int gibi olur


7
select min(convert(int, somebitfield))

veya sonucu bit olarak tutmak istiyorsanız

select convert(bit, min(convert(int, somebitfield)))

6

Aşağıdakini deneyin Not: Min temsil Ve toplama işlevi, Maks temsil Veya toplama işlevi

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

aynı sonuç


5

Bu küçük kod parçası benimle her zaman harika çalıştı:

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

2

ORT (CAST (boolean_column AS FLOAT)) AŞIRI (...) BOOLEAN_AGGREGATE OLARAK

Bulanık bir boole verin:

  • 1 bunun tamamen Doğru olduğunu gösterir;

  • 0 bunun tamamen yanlış olduğunu gösterir;

  • arasında bir değer] 0..1 [kısmi eşleşmeyi gösterir ve doğruluk yüzdesi olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.