Có thể chỉ định điều kiện trong Count () không?


391

Có thể chỉ định một điều kiện trong Count()? Tôi chỉ muốn đếm các hàng có, ví dụ: "Người quản lý" trong cột Vị trí.

Tôi muốn làm điều đó trong câu lệnh đếm, không sử dụng WHERE; Tôi đang hỏi về điều đó bởi vì tôi cần tính cả Người quản lý và Người khác giống nhau SELECT(một cái gì đó giống như Count(Position = Manager), Count(Position = Other))vậy WHEREkhông có ích cho tôi trong ví dụ này.


4
Boo cho tất cả người dùng *, sử dụng Count (someColumnInYourTable) trong đó Position = 'Manager'
Mark Dickinson

6
@Mark: Trên tất cả các cơ sở dữ liệu hiện đại, điều này không tạo ra sự khác biệt nào .
Philippe Leybaert

5
@Mark & ​​Philippe: Thật ra nó có thể tạo ra sự khác biệt lớn. Nếu trường là nullable và không được lập chỉ mục, truy vấn cần chạm vào mọi bản ghi trong bảng, do đó, sử dụng Count (*) và Count (trường) có thể cho kết quả differnet và hiệu suất khác nhau.
Guffa

4
Tôi đã phân tích các kế hoạch thực hiện cho số lượng (*) so với số lượng (x) trong nhiều năm và cho đến nay tôi vẫn chưa tìm thấy một kế hoạch nào cho thấy sự khác biệt về hiệu suất. Đó là lý do tại sao tôi thực sự muốn xem một ví dụ về truy vấn có sự khác biệt.
Philippe Leybaert

3
@Matthew: chúng tôi không nói về SELECT *, nhưng SELECT COUNT(*), đó là một con thú hoàn toàn khác.
Philippe Leybaert

Câu trả lời:


663

Nếu bạn không thể tự giới hạn truy vấn bằng một wheremệnh đề, bạn có thể sử dụng thực tế là counttổng hợp chỉ tính các giá trị khác không:

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

Bạn cũng có thể sử dụng sumtổng hợp theo cách tương tự:

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

nếu trường của tôi là số nguyên và tôi muốn khớp null. nó không hoạt động theo cách này, chọn tính (trường hợp IntegerField khi 'NULL' rồi 1 kết thúc null khác) từ
Faizan

2
@Faizan nullthật đặc biệt. Sử dụngcase when IntegerField is null then ...
Peet Brits

Khi làm việc với các trường boolean, bạn có thể sử dụng:SUM(CONVERT(int, IsManager))
Simon_Weaver

2
SQL Server ngụ ý một else nullcho casebáo cáo, vì vậy các count()ví dụ có thể là 10 ký tự ngắn hơn (nếu bạn đếm không gian).
Michael - Clay Shirky ở đâu

212

Giả sử bạn không muốn hạn chế các hàng được trả về vì bạn cũng đang tổng hợp các giá trị khác, bạn có thể làm như thế này:

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

Giả sử trong cùng một cột bạn có các giá trị của Người quản lý, Người giám sát và Trưởng nhóm, bạn có thể nhận được số lượng của từng cột như sau:

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
@RedFilter Thậm chí không cần thiết phải chỉ định elsephần, chỉ cần endnó ngay sau 1.
Denis Valeev

7
@Denis: chính xác - Tôi thường để lại phần này elsevì nó ghi lại tốt hơn các kết quả của câu lệnh tình huống, đặc biệt là cho các nhà phát triển SQL mới. Để cho ngắn gọn, nó có thể được gỡ bỏ trong trường hợp này.
RedFilter

30

Câu trả lời của @Guffa là tuyệt vời, chỉ cần chỉ ra rằng có thể sạch hơn với câu lệnh IF

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

21

Tùy thuộc vào ý của bạn, nhưng cách hiểu khác về ý nghĩa là nơi bạn muốn đếm các hàng với một giá trị nhất định, nhưng không muốn hạn chế SELECTCHỈ các hàng đó ...

Bạn sẽ làm điều đó bằng cách sử dụng SUM()một mệnh đề trong, như thế này thay vì sử dụng COUNT(): vd

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

Bạn cũng có thể sử dụng Từ khóa Pivot nếu bạn đang sử dụng SQL 2005 trở lên

thêm thông tin và từ Technet

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

Kiểm tra tập dữ liệu

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

Bạn có nghĩa là chỉ này:

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

Nếu vậy, thì yup hoạt động!


1
Bản chỉnh sửa cho thấy anh ta không muốn hạn chế các hàng bằng mệnh đề WHERE
KinSlayerUY

4

Tôi biết điều này thực sự cũ, nhưng tôi thích NULLIFthủ thuật cho các kịch bản như vậy và cho đến nay tôi không tìm thấy nhược điểm nào. Chỉ cần xem bản sao và ví dụ có thể dán của tôi, tuy không thực tế lắm, nhưng trình bày cách sử dụng nó.

NULLIF có thể cung cấp cho bạn một tác động tiêu cực nhỏ đến hiệu suất, nhưng tôi đoán nó vẫn phải nhanh hơn các truy vấn con.

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

Nhận xét đánh giá cao :-)


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

2

Tôi nghĩ bạn có thể sử dụng mệnh đề WHERE đơn giản để chỉ chọn một số bản ghi.


Tại sao tôi nhận được một phiếu bầu xuống? Sau khi tôi trả lời (hoặc có thể là cùng một lúc), nhiều người đã trả lời điều tương tự và họ không nhận được bất kỳ sự phản đối nào. / :(
NawaMan

4
Bạn nhận được một downvote vì câu hỏi là "chỉ định điều kiện trong Đếm" KHÔNG "Đếm giá trị theo điều kiện". Vì vậy, bạn đang trả lời câu hỏi sai
Radon8472

3
Thật không công bằng khi hạ thấp câu trả lời, khi câu trả lời được viết, đó là một giải pháp chính xác cho câu hỏi .... anh ấy đã thêm văn bản thêm 4 phút sau câu trả lời này!
Peter

2

Dưới đây là những gì tôi đã làm để có được một bộ dữ liệu bao gồm cả tổng và số đáp ứng các tiêu chí, trong mỗi container vận chuyển. Điều đó cho phép tôi trả lời câu hỏi "Có bao nhiêu container vận chuyển có nhiều hơn X% các mặt hàng trên kích thước 51"

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

Sử dụng điều này, bạn sẽ nhận được số lượng cho người quản lý

Select Position, count(*) as 'Position Counter'
from your_table 
group by Position 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.