2015-08-27 22 views
5

Próbuję użyć numeru SEDE, aby określić liczbę wszystkich znaczków opartych na tagach. Moja typowa strategia to podsumować:Jak mogę uzyskać liczbę kolumn typu bitowego?

select sum(TagBased) 
from Badges 

Niestety, ponieważ TagBased to wartość bitu, otrzymuję ten błąd:

Operand data type bit is invalid for sum operator.

Z desperacji próbowałem Count:

select count(TagBased) 
from Badges 

Zlicza to liczbę wartości innych niż NULL, które w tym przypadku są identyczne z count(*). Jak więc wykorzystać wartość bitową w agregacie?

Odpowiedz

10

Jeśli tylko zajrzeć do odznak tag-based i nie dbają o resztę, można przejść test, aby w przypadku gdy klauzula:

select count(*) 
from Badges 
where TagBased = 1 

Rozwiązanie kanoniczny byłoby rzucić wartość bitu do rodzaju danych, które można podsumować:

select sum(cast(TagBased as decimal)) 
from Badges 

jeszcze bardziej elastycznym rozwiązaniem jest zrobić konwersję się z CASE statement:

select sum(case TagBased when 1 then 100.0 end)/count(*) tag_based_per 
from Badges 

Alternatywnie, w nowszych wersjach SQL Server Jest takie IIF function:

select sum(iif(TagBased = 1, 1, 0)) 
from Badges 

Wreszcie, jeśli jesteś w golfa, można oszukać SQL do konwersji bitu dla Ciebie:

select sum(TagBased+0) 
from Badges 

Zaliczenie tej techniki idzie do odpowiedzi na bardziej szczegółowe pytanie Kenneth Baltrinic.

Dla odniesienia (i potencjalnego rozwidlenia): my test queries.

+0

może możesz dodać ten też "wybierz sumę (TagBased i 1) z Odznak"? – Saidolim

+0

Nigdy nie byłem na http://data.stackexchange.com dopóki nie zobaczyłem twojego ostatniego linku - teraz czuję, że reszta mojego wieczoru wyparuje ... – TwoStraws

1

Inny sposób COUNT tylko jeden z BIT kolumny jest użycie NULLIF:

SELECT COUNT(NULLIF(TagBased,0)) AS result 
FROM Badges b; 

LiveDemo


Jeszcze jeden sposób wykorzystujący SIGN:

SELECT SUM(SIGN(TagBased)) AS result 
FROM Badges b; 

LiveDemo2


I jeszcze jeden sposób.Nie jestem pewien, dlaczego pisałem go:

SELECT DISTINCT TOP 1 RANK() OVER(ORDER BY TagBased DESC) - 1 
FROM Badges b 
ORDER BY 1 DESC; 

LiveDemo3

1

Jednym ze sposobów, z użyciem operatorów bitowych.

select sum(TagBased&1) from Badges 

Ogólnie można zapisać kilka wartości bitów w jednej liczbie całkowitej. Na przykład mam 5 rodzajów bages. Można umieścić wartości jak:

  • 1 - Kodeks
  • 2 - bitowym
  • 4 - bajt
  • 8 - programowanie

jeśli trzeba ustawić Code i byte jednocześnie czas. To będzie 1 + 4 = 5

Teraz jak liczyć Code bages liczyć

select sum(TagBased & 1) from Badges 

Teraz jak liczyć Byte bages liczyć

select sum(TagBased & 4)/4 from Badges 

Teraz w tym samym czasie, Code i Byte bages liczyć na wszystkich

select count(TagBased & 5) from Badges where TagBased & 5 > 0 
Powiązane problemy