2011-12-15 23 views
5

Tôi có một bảng với hai cột: một cặp vợ chồng id và một số "dấu" cho rằng cặp vợ chồng. Tôi muốn có kết quả liệt kê số cặp vợ chồng có số x là hoặc nhiều hơn cho mỗi giá trị của x. Vì vậy, đầu vào của tôi trông giống như:Đếm số hàng với giá trị lớn hơn hoặc bằng một giá trị từ cột khác trong SQL

 
| couple_id | num_marks | 
|-----------+-----------| 
|   9 |   7 | 
|   6 |   6 | 
|   8 |   6 | 
|   2 |   5 | 
|   3 |   4 | 
|   5 |   4 | 
|   1 |   3 | 
|   4 |   3 | 
|  10 |   2 | 
|   7 |   1 | 

Và tôi muốn để có được kết quả:

 
| num_marks | num_couples | 
|-----------+-------------| 
|   7 | 1   | 
|   6 | 3   | 
|   5 | 4   | 
|   4 | 6   | 
|   3 | 8   | 
|   2 | 9   | 
|   1 | 10   | 

Tức là đã có 1 cặp vợ chồng với 7 hoặc nhiều nhãn hiệu, 3 cặp vợ chồng với 6 hoặc nhiều nhãn hiệu, 4 ​​ cặp vợ chồng có 5 hoặc nhiều nhãn hiệu, vv Tôi đã có thể đưa ra một truy vấn để trở lại số lượng các cặp vợ chồng với chính xácn dấu:

SELECT num_marks, 
     count(couple_id) AS num_couples 
    FROM table_name 
    GROUP BY num_marks 
    ORDER BY num_marks DESC; 

nào mang lại:

 
| num_marks | num_couples | 
|-----------+-------------| 
|   7 |   1 | 
|   6 |   2 | 
|   5 |   1 | 
|   4 |   2 | 
|   3 |   2 | 
|   2 |   1 | 
|   1 |   1 | 

Ie có 1 cặp với 7 điểm, 2 cặp với 6 điểm, 1 với 5, v.v. Có phải là có cách thuận tiện để tổng hợp giá trị của mỗi hàng với những số trên không? Tôi có thể làm điều đó ở cấp độ ứng dụng, nhưng nó có vẻ giống như loại điều mà thực sự thuộc về cơ sở dữ liệu.

Trả lời

5

này có thể không đặc biệt hiệu quả nhưng phải hoàn thành công việc:

SELECT t1.num_marks,  
    (SELECT count(t2.couple_id) 
    FROM table_name t2 
    WHERE t2.num_marks >= t1.num_marks 
    ) AS num_couples 
FROM table_name t1 
GROUP BY t1.num_marks 
ORDER BY t1.num_marks DESC; 

Edit: Bạn có thể sử dụng một sub query trong lựa chọn, từ, ở đâu, nhóm bằng và có các điều khoản của một truy vấn và nếu bạn tham chiếu 'truy vấn' chính/bên ngoài thì nó sẽ đánh giá truy vấn con cho mỗi hàng, sau đó nó được gọi là correlated subquery. Theo câu trả lời của Damien, bạn cũng có thể sử dụng CTE - CTE's có thể cải thiện khả năng đọc và cũng có thể thực hiện đệ quy và tự tham gia IMO dễ dàng hơn rất nhiều.

Truy vấn phụ AFAIK được hỗ trợ trong hầu hết các câu lệnh SQL.

+0

Đó sởn rực rỡ! Tôi không biết bạn có thể có 'SELECT' làm cột. SQL chuẩn đó có hoạt động được không, ví dụ: SQLite và Postgres? Ngoài ra, 'table_name' của tôi không thực sự là một bảng, nó là một sự tự hào lớn' SELECT'; điều đó sẽ phá vỡ mọi thứ? – haxney

+1

@haxney - Tôi đã chỉnh sửa - có, bạn có thể thay thế tên_bảng bằng một truy vấn khác, bạn sẽ cần phải bí danh nó để sử dụng nó trên lựa chọn bên ngoài. – StuartLC

4

Bạn có thể sử dụng RANK() chức năng để tìm ra nơi mỗi kết quả xếp, sau đó chỉ cần thêm số lượng kết quả gắn vào rank rằng:

create table #T (couple_id int,num_marks int) 
insert into #T (couple_id,num_marks) 
select 9 ,   7 union all 
select 6 ,   6 union all 
select 8 ,   6 union all 
select 2 ,   5 union all 
select 3 ,   4 union all 
select 5 ,   4 union all 
select 1 ,   3 union all 
select 4 ,   3 union all 
select 10 ,   2 union all 
select 7 ,   1 

;with Ranked as (
    select num_marks,RANK() OVER (ORDER BY num_marks desc) as rk from #T 
) 
select num_marks,rk + COUNT(*) -1 as Result from Ranked 
group by num_marks,rk 

Cung cấp:

num_marks Result 
----------- -------------------- 
7   1 
6   3 
5   4 
4   6 
3   8 
2   9 
1   10 

(7 row(s) affected) 

(Tất nhiên, nếu bạn cần kết quả theo một thứ tự đặc biệt, đừng quên thêm một khoản ORDER BY - trật tự trên chỉ là một tai nạn hạnh phúc)