COUNT DISTINCT có ĐIỀU KIỆN


103

Tôi muốn đếm số lượng các mục riêng biệt trong một cột tuân theo một điều kiện nhất định, ví dụ: nếu bảng như thế này:

tag | entryID
----+---------
foo | 0
foo | 0
bar | 3

Nếu tôi muốn đếm số lượng thẻ riêng biệt là "số thẻ" và đếm số thẻ khác biệt có id mục nhập> 0 là "số thẻ tích cực" trong cùng một bảng, tôi phải làm gì?

Bây giờ tôi đang đếm từ hai bảng khác nhau trong đó trong bảng thứ hai, tôi chỉ chọn những hàng có entryID lớn hơn 0. Tôi nghĩ cần có một cách nhỏ gọn hơn để giải quyết vấn đề này.

Câu trả lời:


256

Bạn có thể thử điều này:

select
  count(distinct tag) as tag_count,
  count(distinct (case when entryId > 0 then tag end)) as positive_tag_count
from
  your_table_name;

Đầu tiên count(distinct...)là dễ dàng. Cái thứ hai, trông hơi phức tạp, thực sự giống cái đầu tiên, ngoại trừ việc bạn sử dụng case...whenmệnh đề. Trong case...whenmệnh đề, bạn chỉ lọc các giá trị dương. Zeros hoặc các giá trị âm sẽ được đánh giá là nullvà sẽ không được tính vào số lượng.

Một điều cần lưu ý ở đây là điều này có thể được thực hiện bằng cách đọc bảng một lần. Khi có vẻ như bạn phải đọc cùng một bảng hai lần hoặc nhiều hơn, nó thực sự có thể được thực hiện bằng cách đọc một lần, trong hầu hết thời gian. Kết quả là, nó sẽ hoàn thành tác vụ nhanh hơn rất nhiều với ít I / O hơn.


2
Nhưng sau đó thì positive_tag_count có khác biệt không?
derekhh 27/12/12

Truy vấn đã chỉnh sửa vẫn không giải quyết được vấn đề - điều này hiện không hoạt động trên các giá trị entryId riêng biệt chứ không phải các thẻ riêng biệt?
BrianC 27/12/12

Đây là một lời cảnh báo thực sự thông minh.
Luc

Tôi có nhiều cột trong phân biệt của mình (ví dụ về số lượng (thẻ riêng biệt, ngày tháng)). Có cách nào để có nhiều cột trong mệnh đề then. Nếu tôi chỉ làm một thẻ, ngày nó ném một ngoại lệ phân tích cú pháp
Crusaderpyro

@Crusaderpyro Điều đó nằm ngoài phạm vi của câu hỏi ban đầu. Tôi muốn tạo một câu hỏi mới cho điều đó.
ntalbs

2

Hãy thử câu lệnh sau:

select  distinct A.[Tag],
     count(A.[Tag]) as TAG_COUNT,
     (SELECT count(*) FROM [TagTbl] AS B WHERE A.[Tag]=B.[Tag] AND B.[ID]>0)
     from [TagTbl] AS A GROUP BY A.[Tag]

Trường đầu tiên sẽ là thẻ, trường thứ hai sẽ là số toàn bộ, trường thứ ba sẽ là số dương.


1

Điều này có thể hoạt động:

SELECT Count(tag) AS 'Tag Count'
FROM Table
GROUP BY tag

SELECT Count(tag) AS 'Negative Tag Count'
FROM Table
WHERE entryID > 0
GROUP BY tag

0

Điều này cũng có thể hoạt động:

SELECT 
    COUNT(DISTINCT T.tag) as DistinctTag,
    COUNT(DISTINCT T2.tag) as DistinctPositiveTag
FROM Table T
    LEFT JOIN Table T2 ON T.tag = T2.tag AND T.entryID = T2.entryID AND T2.entryID > 0

Bạn cần điều kiện entryID trong phép nối bên trái thay vì trong mệnh đề where để đảm bảo rằng bất kỳ mục nào chỉ có entryID bằng 0 đều được tính đúng trong DISTINCT đầu tiên.


1
Truy vấn này đọc bảng hai lần. Nó có thể được thực hiện bằng cách đọc bảng chỉ một lần.
ntalbs 27/12/12

0

Mã đếm sự kết hợp duy nhất / khác biệt của Thẻ và ID mục nhập khi [Id mục nhập]> 0

select count(distinct(concat(tag,entryId)))
from customers
where id>0

Trong đầu ra, nó sẽ hiển thị số lượng các giá trị duy nhất. Hy vọng điều này sẽ giúp

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.