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

Ass*_*vie 152 sql performance

我有一张学生桌:

id | age
--------
0  | 25
1  | 25
2  | 23
Run Code Online (Sandbox Code Playgroud)

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

id | age | count
----------------
0  | 25  | 2
1  | 25  | 2
2  | 23  | 1
Run Code Online (Sandbox Code Playgroud)

这样做最有效的方法是什么?我担心子查询会很慢,我想知道是否有更好的方法.在那儿?

Mik*_*scu 227

这应该工作:

SELECT age, count(age) 
  FROM Students 
 GROUP by age
Run Code Online (Sandbox Code Playgroud)

如果您还需要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
Run Code Online (Sandbox Code Playgroud)

  • 对于第二个查询,外部选择应该在C.cnt上,因为没有S.cnt,否则会出现错误:无效的列名'cnt' (2认同)

Jer*_*que 25

如果您使用的是Oracle,那么称为分析的功能就可以实现.它看起来像这样:

select id, age, count(*) over (partition by age) from students;
Run Code Online (Sandbox Code Playgroud)

如果您不使用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
Run Code Online (Sandbox Code Playgroud)

  • +1,第一个查询适用于SQL Server 2005及更高版本 (3认同)
  • 仅供参考,在SQL Server 2005上,第二个查询的运行成本几乎是第一个查询的一半(使用_SET SHOWPLAN_ALL ON_)。我以为第一个会更好,但是老派的加入击败了它。 (2认同)

Dam*_*ian 18

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

SELECT age, count(*)
FROM Students 
GROUP by age
ORDER BY age
Run Code Online (Sandbox Code Playgroud)

  • 如果您按年龄分组,那么您只会获得一个 25 岁且计数为 2 的条目(当他们实际上想要 2 个计数为 2 的条目以及给定示例的单独 id 时)? (2认同)
  • 伊恩,感谢您的反馈。您是否针对 MS SQL 2000 DB 执行了索赔? (2认同)

quo*_*soo 7

我会做的事情如下:

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;
Run Code Online (Sandbox Code Playgroud)


Red*_*ter 5

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
Run Code Online (Sandbox Code Playgroud)