SQL에서 중앙값(MEDIAN) 계산
소개
SQL에서 중앙값을 산출하는 방법은, 사용하기 때문에 성능이 매우 나쁜 것 같습니다.
거기서, 퍼포먼스를 개선하는 방법으로서, 건수의 집계를 실시하고 나서 자기 결합하는 방법을 생각해 왔으므로 소개합니다.
해설
간단한 샘플 데이터로 짝수 짝수 건수와 홀수 홀수 건 데이터를 준비합니다.
짝수 데이터
값
1
1
2
3
홀수건 데이터
값
1
1
2
3
3
(1) 우선 값별로 데이터 건수를 집계한다
SELECT
値
, COUNT(*) AS 件数
FROM 偶数件データ
GROUP BY 値
전술 한 테이블은 뷰, 임시 테이블 또는 서브 쿼리로서 후속 SQL에서 집계 데이터로 표현된다.
짝수 개의 데이터 실행 결과
값
건수
1
2
2
1
3
1
홀수건 데이터 실행 결과
값
건수
1
2
2
1
3
2
(2) 건수의 누적 계산
SELECT
Z.値
, Z.件数
, SUM(A.件数) AS 累積件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数
짝수 개의 데이터 실행 결과
값
건수
누적 건수
1
2
2
2
1
3
3
1
4
홀수건 데이터 실행 결과
값
건수
누적 건수
1
2
2
2
1
3
3
2
5
(3) 누적 전 건수(해당 레코드의 건수를 가산하기 전의 건수)와 중간 건수(전체의 절반에 해당하는 건수)를 합쳐서 표시한다
SELECT
Z.値
, Z.件数
, SUM(A.件数) - Z.件数 AS 累積前件数
, SUM(A.件数) AS 累積件数
, (SELECT SUM(件数)/2 FROM 集計データ) AS 中間件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数
짝수 개의 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
1
2
0
2
2
2
1
2
3
2
3
1
3
4
2
홀수건 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
1
2
0
2
2.5
2
1
2
3
2.5
3
2
3
5
2.5
(4) 누적 전 건수 ≤ 중간 건수 ≤ 누적 건수를 만족하는 레코드를 추출한다
SELECT *
FROM
(SELECT
Z.値
, Z.件数
, SUM(A.件数) - Z.件数 AS 累積前件数
, SUM(A.件数) AS 累積件数
, (SELECT SUM(件数)/2 FROM 集計データ) AS 中間件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数) AS SUB
WHERE 中間件数 BETWEEN 累積前件数 AND 累積件数
짝수 개의 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
1
2
0
2
2
2
1
2
3
2
※1레코드 또는 2레코드가 대상이 됩니다.
홀수건 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
2
1
2
3
2.5
※반드시 1레코드만이 대상이 됩니다.
(5) (4)에서 추출한 레코드의 값의 평균을 산출한다.
SELECT AVG(値) AS 中央値
FROM
(SELECT
Z.値
, Z.件数
, SUM(A.件数) AS 累積件数
, (SELECT SUM(件数) FROM 集計データ) AS 総件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数) AS SUB
WHERE 総件数/2 BETWEEN 累積件数 - 件数 AND 累積件数
※일부 표현을 깨끗이 하기 위해서, 계산 순서를 바꾸고 있습니다.
짝수 개의 데이터 실행 결과
중앙값
1.5
홀수건 데이터 실행 결과
중앙값
2
여기 기사의 질문 4의 실행 결과
(3)의 실행 결과가 이하와 같고, 노란색의 2 레코드가 (4)의 추출 대상이 되고, 결과는 220000과 235000의 평균으로 227500이 됩니다
여기
참고로 분석 함수를 사용한 SQL의 예는 다음과 같습니다.
WITH SUB AS (
SELECT
値
, 件数
, SUM(件数) OVER( ORDER BY 値) AS 累積件数
, SUM(件数) OVER() AS 総件数
FROM 集計データ
)
SELECT AVG(値) AS 中央値
FROM SUB
WHERE 総件数/2 BETWEEN 累積件数 - 件数 AND 累積件数
잘 생각하면, 분석 함수를 사용한 경우는 자기 결합이 불필요하게 되므로, 집계 데이터를 일부러 사용할 필요도 없기 때문에 이하의 내용으로 가능합니다
WITH SUB AS (
SELECT
値
, ROW_NUMBER() OVER (ORDER BY 値) AS 連番
, COUNT(*) OVER () AS 総件数
FROM 元テーブル
)
SELECT AVG(値) AS 中央値
FROM SUB
WHERE 総件数/2 BETWEEN 連番 - 1 AND 連番
Reference
이 문제에 관하여(SQL에서 중앙값(MEDIAN) 계산), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/takahasinaoki/items/1dd99f69eaef677b8c14
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
간단한 샘플 데이터로 짝수 짝수 건수와 홀수 홀수 건 데이터를 준비합니다.
짝수 데이터
값
1
1
2
3
홀수건 데이터
값
1
1
2
3
3
(1) 우선 값별로 데이터 건수를 집계한다
SELECT
値
, COUNT(*) AS 件数
FROM 偶数件データ
GROUP BY 値
전술 한 테이블은 뷰, 임시 테이블 또는 서브 쿼리로서 후속 SQL에서 집계 데이터로 표현된다.짝수 개의 데이터 실행 결과
값
건수
1
2
2
1
3
1
홀수건 데이터 실행 결과
값
건수
1
2
2
1
3
2
(2) 건수의 누적 계산
SELECT
Z.値
, Z.件数
, SUM(A.件数) AS 累積件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数
짝수 개의 데이터 실행 결과
값
건수
누적 건수
1
2
2
2
1
3
3
1
4
홀수건 데이터 실행 결과
값
건수
누적 건수
1
2
2
2
1
3
3
2
5
(3) 누적 전 건수(해당 레코드의 건수를 가산하기 전의 건수)와 중간 건수(전체의 절반에 해당하는 건수)를 합쳐서 표시한다
SELECT
Z.値
, Z.件数
, SUM(A.件数) - Z.件数 AS 累積前件数
, SUM(A.件数) AS 累積件数
, (SELECT SUM(件数)/2 FROM 集計データ) AS 中間件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数
짝수 개의 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
1
2
0
2
2
2
1
2
3
2
3
1
3
4
2
홀수건 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
1
2
0
2
2.5
2
1
2
3
2.5
3
2
3
5
2.5
(4) 누적 전 건수 ≤ 중간 건수 ≤ 누적 건수를 만족하는 레코드를 추출한다
SELECT *
FROM
(SELECT
Z.値
, Z.件数
, SUM(A.件数) - Z.件数 AS 累積前件数
, SUM(A.件数) AS 累積件数
, (SELECT SUM(件数)/2 FROM 集計データ) AS 中間件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数) AS SUB
WHERE 中間件数 BETWEEN 累積前件数 AND 累積件数
짝수 개의 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
1
2
0
2
2
2
1
2
3
2
※1레코드 또는 2레코드가 대상이 됩니다.
홀수건 데이터 실행 결과
값
건수
누적 전 건수
누적 건수
중간 건수
2
1
2
3
2.5
※반드시 1레코드만이 대상이 됩니다.
(5) (4)에서 추출한 레코드의 값의 평균을 산출한다.
SELECT AVG(値) AS 中央値
FROM
(SELECT
Z.値
, Z.件数
, SUM(A.件数) AS 累積件数
, (SELECT SUM(件数) FROM 集計データ) AS 総件数
FROM 集計データ AS Z,
集計データ AS A
WHERE Z.値 >= A.値
GROUP BY
Z.値
, Z.件数) AS SUB
WHERE 総件数/2 BETWEEN 累積件数 - 件数 AND 累積件数
※일부 표현을 깨끗이 하기 위해서, 계산 순서를 바꾸고 있습니다.짝수 개의 데이터 실행 결과
중앙값
1.5
홀수건 데이터 실행 결과
중앙값
2
여기 기사의 질문 4의 실행 결과
(3)의 실행 결과가 이하와 같고, 노란색의 2 레코드가 (4)의 추출 대상이 되고, 결과는 220000과 235000의 평균으로 227500이 됩니다
여기
참고로 분석 함수를 사용한 SQL의 예는 다음과 같습니다.
WITH SUB AS (
SELECT
値
, 件数
, SUM(件数) OVER( ORDER BY 値) AS 累積件数
, SUM(件数) OVER() AS 総件数
FROM 集計データ
)
SELECT AVG(値) AS 中央値
FROM SUB
WHERE 総件数/2 BETWEEN 累積件数 - 件数 AND 累積件数
잘 생각하면, 분석 함수를 사용한 경우는 자기 결합이 불필요하게 되므로, 집계 데이터를 일부러 사용할 필요도 없기 때문에 이하의 내용으로 가능합니다
WITH SUB AS (
SELECT
値
, ROW_NUMBER() OVER (ORDER BY 値) AS 連番
, COUNT(*) OVER () AS 総件数
FROM 元テーブル
)
SELECT AVG(値) AS 中央値
FROM SUB
WHERE 総件数/2 BETWEEN 連番 - 1 AND 連番
Reference
이 문제에 관하여(SQL에서 중앙값(MEDIAN) 계산), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/takahasinaoki/items/1dd99f69eaef677b8c14텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)