我有一个包含两列的表:一对id和一些“标记”
一对。我想要一个结果,其中列出了具有x
标记的夫妻数量
或x
的每个值的更多或更多。所以我的输入如下:
| couple_id | num_marks | |-----------+-----------| | 9 | 7 | | 6 | 6 | | 8 | 6 | | 2 | 5 | | 3 | 4 | | 5 | 4 | | 1 | 3 | | 4 | 3 | | 10 | 2 | | 7 | 1 |
我想得到结果:
| num_marks | num_couples | |-----------+-------------| | 7 | 1 | | 6 | 3 | | 5 | 4 | | 4 | 6 | | 3 | 8 | | 2 | 9 | | 1 | 10 |
即。有一对夫妇有7个或更多的分数,3对夫妇有6个或更多的分数,4
有5个或更多分数的夫妇等我已经能够提出一个查询
返回完全 n
标记的夫妻数量:
SELECT num_marks,
count(couple_id) AS num_couples
FROM table_name
GROUP BY num_marks
ORDER BY num_marks DESC;
哪个收益率:
| num_marks | num_couples | |-----------+-------------| | 7 | 1 | | 6 | 2 | | 5 | 1 | | 4 | 2 | | 3 | 2 | | 2 | 1 | | 1 | 1 |
即。有1对夫妇有7个标记,2对夫妇有6个标记,1个有5个,等等 有一种方便的方法可以有效地将每行的值与上面的值相加 它?我可以在应用程序级别执行此操作,但它似乎就是这种情况 它真的属于数据库。
答案 0 :(得分:7)
这可能不是特别有效,但应该完成工作:
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;
修改: 您可以在查询的select,from,where,group by和having子句中使用sub query,如果引用main / outer'query',那么它将评估每行的子查询,然后它是称为correlated subquery。 (因此关于表现的警告)
根据Damien的回答,你也可以使用CTE - CTE可以提高可读性,并且使IMO的递归和自连接变得更加容易。
大多数SQL都支持AFAIK子查询。
答案 1 :(得分:4)
您可以使用RANK()函数计算每个结果排名的位置,然后只需将绑定结果的数量添加到该排名中:
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
给出:
num_marks Result
----------- --------------------
7 1
6 3
5 4
4 6
3 8
2 9
1 10
(7 row(s) affected)
(当然,如果您需要按特定顺序排列结果,请不要忘记添加ORDER BY
条款 - 以上排序只是一个快乐的事故)