Count () içinde koşul belirtmek mümkün mü?


391

İçinde bir koşul belirtmek mümkün mü Count() ? Yalnızca Konum sütununda "Yönetici" olan satırları saymak istiyorum.

Ben sayım deyiminde kullanarak değil, kullanmak istiyorum WHERE; Aynı hem Yöneticileri ve Diğer saymak gerekir çünkü bu konuda soruyorum SELECTgibi (bir şey Count(Position = Manager), Count(Position = Other))bu yüzden WHEREbu örnekte benim için kullanılmasıdır.


4
Tüm * kullanıcılara boo, Count = SomeColumnInYourTable) kullanın burada Position = 'Manager'
Mark Dickinson

6
@Mark: Tüm modern veritabanlarında bu bir fark yaratmaz .
Philippe Leybaert

5
@ Mark & ​​Philippe: Aslında büyük bir fark yaratabilir. Alan boş bırakılabilir ve dizine eklenmemişse, sorgunun tablodaki her kayda dokunması gerekir, bu nedenle count (*) ve count (field) kullanımı farklı sonuçlar ve farklı performans verebilir.
Guffa

4
Count (*) vs count (x) için yıllardır yürütme planlarını analiz ettim ve şimdiye kadar performansta bir fark gösteren tek bir tane bulamadım. Bu yüzden gerçekten bir farkın olduğu bir sorgu örneği görmek istiyorum.
Philippe Leybaert

3
@Matthew: Bahsetmiyoruz SELECT *, ama SELECT COUNT(*)bu tamamen farklı bir canavar.
Philippe Leybaert

Yanıtlar:


663

Sorgunun kendisini yalnızca bir wherecümle ile sınırlayamazsanız , counttoplamın yalnızca null olmayan değerleri sayması gerçeğini kullanabilirsiniz :

select count(case Position when 'Manager' then 1 else null end)
from ...

Toplamı da sumbenzer şekilde kullanabilirsiniz:

select sum(case Position when 'Manager' then 1 else 0 end)
from ...

alanım tamsayı ise ve null ile eşleşmek istersem ne olur? ondan bu şekilde select count (dava IntegerField ardından 'BOŞ' 1 başka boş ucu) çalışmıyor
faizan

2
@Faizan nullözeldir. Kullanımcase when IntegerField is null then ...
Peet Brits

Boole alanlarıyla çalışırken şunları kullanabilirsiniz:SUM(CONVERT(int, IsManager))
Simon_Weaver

2
SQL Server bir else nullfor caseifadeleri anlamına gelir , bu nedenle count()örnek 10 karakter daha kısa olabilir (alanı sayarsanız).
Michael - Clay Shirky

212

Diğer değerleri de topladığınız için döndürülen satırları kısıtlamak istemediğinizi varsayarsak, bunu şu şekilde yapabilirsiniz:

select count(case when Position = 'Manager' then 1 else null end) as ManagerCount
from ...

Aynı sütun içinde Yönetici, Süpervizör ve Ekip Lideri değerlerine sahip olduğunuzu varsayalım, her birinin sayımlarını şöyle elde edebilirsiniz:

select count(case when Position = 'Manager' then 1 else null end) as ManagerCount,
    count(case when Position = 'Supervisor' then 1 else null end) as SupervisorCount,
    count(case when Position = 'Team Lead' then 1 else null end) as TeamLeadCount,
from ...

3
Bu belirtmek için bile gerekli değil @RedFilter elsesadece bir bölümünü endbu hemen sonra 1.
Denis Valeev

7
@Denis: doğru - Ben elseözellikle novie SQL geliştiricileri için, vaka deyiminin sonuçlarını daha iyi belgelediğinden sık sık içinde bırakın . Kısacası, bu durumda çıkarılabilir.
RedFilter

30

@Guffa'nın cevabı mükemmel, sadece bir IF ifadesiyle daha temiz olduğuna dikkat edin

select count(IF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...

21

Ne demek istediğinize bağlıdır, ancak anlamın diğer yorumu, belirli bir değere sahip satırları saymak istediğiniz yerdir, ancak SELECT bu satırları SADECE ...

Bunu SUM(), yerine bir cümle kullanarak yaparsınız , COUNT()örneğin:

SELECT SUM(CASE WHEN Position = 'Manager' THEN 1 ELSE 0 END) AS ManagerCount,
    SUM(CASE WHEN Position = 'CEO' THEN 1 ELSE 0 END) AS CEOCount
FROM SomeTable

13

SQL 2005 veya üstünü kullanıyorsanız Pivot Anahtar Kelimesini de kullanabilirsiniz

daha fazla bilgi ve Technet'ten

SELECT *
FROM @Users
PIVOT (
    COUNT(Position)
    FOR Position
    IN (Manager, CEO, Employee)
) as p

Test Veri Kümesi

DECLARE @Users TABLE (Position VARCHAR(10))
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('CEO')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')

5

Şunu mu demek istediniz?

SELECT Count(*) FROM YourTable WHERE Position = 'Manager'

Eğer öyleyse, o zaman işe yarıyor!


1
Düzenleme, satırları WHERE yan tümcesi ile sınırlamak istemediğini gösteriyor
KinSlayerUY

4

Bunun gerçekten eski olduğunu biliyorum, ama NULLIFböyle senaryolar için hileyi seviyorum ve şimdiye kadar hiçbir olumsuzluk bulamadım. Yine de çok pratik olmayan, ancak nasıl kullanılacağını gösteren kopyam ve geçmişe dönük örneğime bakın.

NULLIF performans üzerinde küçük bir olumsuz etki yaratabilir, ancak sanırım yine de alt sorgulardan daha hızlı olmalıdır.

DECLARE @tbl TABLE ( id [int] NOT NULL, field [varchar](50) NOT NULL)

INSERT INTO @tbl (id, field)
SELECT 1, 'Manager'
UNION SELECT 2, 'Manager'
UNION SELECT 3, 'Customer'
UNION SELECT 4, 'Boss'
UNION SELECT 5, 'Intern'
UNION SELECT 6, 'Customer'
UNION SELECT 7, 'Customer'
UNION SELECT 8, 'Wife'
UNION SELECT 9, 'Son'

SELECT * FROM @tbl

SELECT 
    COUNT(1) AS [total]
    ,COUNT(1) - COUNT(NULLIF([field], 'Manager')) AS [Managers]
    ,COUNT(NULLIF([field], 'Manager')) AS [NotManagers]
    ,(COUNT(1) - COUNT(NULLIF([field], 'Wife'))) + (COUNT(1) - COUNT(NULLIF([field], 'Son'))) AS [Family]
FROM @tbl

Yorumlar takdir :-)


2
SELECT COUNT(*) FROM bla WHERE Position = 'Manager'

2

Ben sadece saymak bazı kayıt seçmek için basit bir WHERE yan tümcesi kullanabilirsiniz düşünüyorum.


Niçin aşağı oy kullanıyorum? Ben cevapladıktan sonra (ya da aynı zamanda olabilir), birçok kişi benzer şeyi cevapladı ve herhangi bir düşüş almıyorlar. / :(
NawaMan

4
Soru "Sayımda koşul belirt" DEĞİL "Değerleri koşullara göre say" olduğundan aşağı not alırsınız. Yani yanlış soruyu
cevaplıyorsunuz

3
Cevabını yazmak için biraz haksızlık, cevap yazıldığında soruya doğru bir çözümdü .... o cevaptan 4 dakika sonra ekstra metin ekledi!
Peter

2

İşte, her gönderim konteynerinde, toplamları ve ölçütleri karşılayan sayıyı içeren bir veri kümesi almak için ne yaptım. "Kaç tane nakliye konteynerinin 51 bedende% X'tan fazla ürün var" sorusunu yanıtlamama izin verin

select
   Schedule,
   PackageNum,
   COUNT (UniqueID) as Total,
   SUM (
   case
      when
         Size > 51 
      then
         1 
      else
         0 
   end
) as NumOverSize 
from
   Inventory 
where
   customer like '%PEPSI%' 
group by
   Schedule, PackageNum


-4

Bunu kullanarak yöneticiler için sayım elde edersiniz

Select Position, count(*) as 'Position Counter'
from your_table 
group by Position 
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.