SQL에서 열 값의 발생을 효율적으로 계산하는 방법은 무엇입니까?


166

학생들의 테이블이 있습니다 :

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

모든 학생과 같은 연령의 학생 수를 계산하는 추가 열을 쿼리하고 싶습니다.

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

가장 효율적인 방법은 무엇입니까? 하위 쿼리가 느려질 것을 두려워하며 더 좋은 방법이 있는지 궁금합니다 . 있습니까?

답변:


256

이것은 작동해야합니다 :

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

2
잘못된 열 이름 'CNT'더 S.cnt가 없기 때문에 두 번째 쿼리에 대한 외부 선택 그렇지 않으면 오류 얻을 C.cnt에 있어야합니다
KM을.

1
pgm_code로 pgm 그룹에서 select case_id, count (pgm_code)를 사용할 때 나에게 오류가 발생합니다. 그것은 표현으로 그룹이 아니라고 말함
Rishabh Agarwal

26

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
참고로, SQL Server 2005에서 두 번째 쿼리는 실행 비용의 거의 절반 ( SET SHOWPLAN_ALL ON 사용 )을 첫 번째로 실행합니다. 나는 첫 번째가 더 좋을 것이라고 생각했지만, 구식 학교는 그것을 이겼습니다.
KM.

1
처리 될 TOTAL ROW COUNT가 다르기 때문에 "오래된 학교 가입이 이겼습니다". 두 번째 쿼리에는 그룹 수가 포함되어 행 수를 크게 줄일 수 있습니다. 첫 번째 쿼리에 DISTINCT를 추가해보십시오. "학생의 DISTINCT id, age, count (*) 이상 (연도 별 파티션)"
quetzalcoatl

19

다른 해결책이 있습니다. 이것은 매우 간단한 구문을 사용합니다. 허용 된 솔루션의 첫 번째 예는 이전 버전의 Microsoft SQL (예 : 2000)에서 작동하지 않았습니다.

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

1
그러나 연령별로 그룹화하면 25 세의 항목이 2로 계산됩니다 (실제로 2의 항목과 2 개의 항목이 있고 주어진 예에서 별도의 ID가있는 경우)?
Ian

1
이안, 피드백 주셔서 감사합니다. MS SQL 2000 DB에 대한 클레임을 실행 했습니까?
데미안

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;

4
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

1

"연령"열의 데이터가 유사한 레코드를 갖는 경우 (예 : 많은 사람이 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*
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.