如何在SQL中有效地计算列值的出现次数?

时间:2009-10-01 13:27:27

标签: sql performance

我有一张学生表:

id | age
--------
0  | 25
1  | 25
2  | 23

我想查询所有学生,还有一个额外的专栏可以计算同一年龄段的学生数量:

id | age | count
----------------
0  | 25  | 2
1  | 25  | 2
2  | 23  | 1

最有效的方法是什么? 我担心子查询会很慢,我想知道是否有更好的方法。有吗?

6 个答案:

答案 0 :(得分:211)

这应该有效:

SELECT age, count(age) 
  FROM Students 
 GROUP by age

如果您还需要id,可以将上面的内容包含在子查询中,如下所示:

SELECT S.id, S.age, C.cnt
  FROM Students  S
       INNER JOIN (SELECT age, count(age) as cnt
                     FROM Students 
                    GROUP BY age) C ON S.age = C.age

答案 1 :(得分:23)

如果您使用的是Oracle,那么称为分析的功能就可以解决问题。它看起来像这样:

select id, age, count(*) over (partition by age) from students;

如果您不使用Oracle,那么您需要加入计数:

select a.id, a.age, b.age_count
  from students a
  join (select age, count(*) as age_count
          from students
         group by age) b
    on a.age = b.age

答案 2 :(得分:17)

这是另一种解决方案。这个使用非常简单的语法。接受的解决方案的第一个示例不适用于旧版本的Microsoft SQL(即2000)

SELECT age, count(*)
FROM Students 
GROUP by age
ORDER BY age

答案 3 :(得分:6)

我会做类似的事情:

select
 A.id, A.age, B.count 
from 
 students A, 
 (select age, count(*) as count from students group by age) B
where A.age=B.age;

答案 4 :(得分:3)

select s.id, s.age, c.count
from students s
inner join (
    select age, count(*) as count
    from students
    group by age
) c on s.age = c.age
order by id

答案 5 :(得分:0)

如果“年龄”栏中的数据具有相似的记录(即许多人年龄为25岁,其他许多人为32岁等等),则会导致混淆对齐每个学生的正确计数。 为了避免这种情况,我也加入了关于学生证的表格。

SELECT S.id, S.age, C.cnt
FROM Students S 
INNER JOIN (SELECT id, age, count(age) as cnt  FROM Students GROUP BY student,age) 
C ON S.age = C.age *AND S.id = C.id*