2011-11-04 42 views
6

Tôi đã dành rất nhiều thời gian để tìm kiếm điều này, vui lòng cho tôi biết nếu trùng lặp.SQL: Nhóm theo số (*) dưới dạng số lượng của tổng số hàng trong bảng

Tôi cần phải viết một truy vấn được nhóm trả về các loại bản ghi với số lượng của từng loại danh mục. Một cái gì đó như thế này:

select categorynum, count(*) from tbl group by categorynum; 

Cho đến nay rất tốt. Bây giờ những gì tôi cần là để xác định% của tổng số của mỗi loại chiếm. Điều tốt nhất tôi đã nghĩ ra là cái này, cái mà tôi không thích, nó cảm thấy bẩn thỉu:

select categorynum, count(*), count(*)/(select count(*) from tbl) from tbl group by categorynum; 

Nó hoạt động, nhưng nó thực sự khiến tôi phải làm theo cách này. Cơ sở dữ liệu tôi sử dụng là cú pháp Postgres tương thích, và count(*) trên bàn thực sự nhanh, vì vậy không có tốc độ cực lớn để thực hiện count(*) trên bảng, mặc dù tôi muốn viết SQL tốt hơn nếu có thể.

Vì vậy, có cách nào tốt hơn để viết nội dung này? Đây là tình huống mà tôi thường gặp phải, vì vậy tôi muốn viết chính xác các truy vấn của mình.

Trả lời

5

Kể từ PostgreSQL hỗ trợ chức năng cửa sổ, bạn có thể làm một cái gì đó như thế này:

select categorynum,count,100*count/(sum(count) over())::numeric as count_pct 
from(
    select categorynum,count(1) 
    from tbl 
    group by categorynum 
)a; 
+0

Điều này phức tạp hơn bản gốc, nhưng nó có chạy nhanh hơn không? Loại truy vấn này có rất nhiều ứng dụng tiềm năng, cảm ơn con trỏ! –

+0

Vâng, nếu có vài giá trị của 'categorynum' liên quan đến số hàng trong' tbl', thì hầu hết công việc sẽ được thực hiện trong truy vấn phụ. Nếu tỷ lệ 'categorynums' khác biệt liên quan đến số hàng trong' tbl' tương đối cao, thì 'tổng hợp' có thể làm chậm quá nhiều. Tôi sẽ kiểm tra kế hoạch truy vấn thông qua một 'giải thích' cho cả hai truy vấn. Và bạn rất hoan nghênh. :) –

1

Bạn cũng có thể làm count (*) trên bàn như một truy vấn riêng biệt và sau đó tham gia rằng với truy vấn ban đầu của bạn trong TỪ phần của câu lệnh SELECT của bạn. Điều đó sẽ nhanh hơn việc đặt nó vào phần CHỌN.

select categorynum, categorycount, total 
from (select categorynum, count(*) as categorycount 
     from tbl 
     group by categorynum) categories, 
    (select count(*) as total from tbl) totals 
+0

Cảm ơn, đó là lựa chọn duy nhất tôi có trước đây ... Điều này là bảng luôn luôn nhận được dữ liệu được thêm vào nó, và tôi cũng sẽ có một truy vấn đơn hơn là chạy hai truy vấn và sau đó nhập các số vào một máy tính/bảng tính để nhận tỷ lệ phần trăm. –

+0

Tôi nghĩ rằng người trả lời có một câu hỏi duy nhất trong đầu ... Tôi sẽ viết một gợi ý vào câu trả lời nơi nó có thể đọc được. – araqnid

+0

mặc dù ví dụ tôi vừa thêm không hiệu quả hơn ví dụ của bạn trong câu hỏi, cả hai đều cho kết quả quét toàn bộ hai bảng. ah tốt, những điều này chỉ thực sự học được bằng cách thử chúng. – araqnid

Các vấn đề liên quan