web-dev-qa-db-ja.com

SQLで列値の出現回数を効率的にカウントする方法

私は学生のテーブルを持っています:

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

すべての生徒と、同じ年齢の生徒の数を数える追加の列をクエリします。

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

これを行う最も効率的な方法は何ですか? 私はサブクエリが遅くなることを恐れています、そしてもっと良い方法があるかどうか疑問に思います。ある?

142
Assaf Lavie

これはうまくいくはずです。

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
211
Mike Dinescu

Oracleを使用しているのであれば、analyticsという機能がうまくいきます。それはこのように見えます:

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
23
Jeremy Bourque

これは別の解決策です。これはとても単純な構文を使います。承認されたソリューションの最初の例は、古いバージョンのMicrosoft SQL(つまり2000)では機能しませんでした。

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

以下のようにします。

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;
6
quosoo
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
3
RedFilter

また、「年齢」列のデータに同様のレコードがある場合(つまり、25歳の人が多く、32歳の人が多いなど)、各生徒に正しい数を合わせる際に混乱が生じます。それを避けるために、私は学生IDのテーブルにも参加しました。

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*
0
afii_palang