- Arawn's Dev Blog
- Outsider's Dev Story
- Toby's Epril
- Benelog
- NHN 개발자 블로그
- SK 플래닛 기술 블로그
- OLC CENTER
- 소프트웨어 경영/공학 블로그
- 모바일 컨버전스
- KOSR - Korea Operating System …
- 넥스트리 블로그
- 리버스코어 ReverseCore
- SLiPP
- 개발자를 위하여... (Nextree 임병인 수석)
- "트위터 부트스트랩: 디자이너도 놀라워할 매끈하고 직관…
- Learning English - The English…
- real-english.com
- 'DataScience/Deep Learning' 카테…
- Deep Learning Summer School, M…
- Deep Learning Courses
민서네집
[MySQL] Group별로 특정 컬럼이 가장 큰 레코드를 추출하는 쿼리 본문
Oracle 에서는 rank(), partition by 등의 분석 함수를 써서 Group 내의 특정 컬럼의 랭킹을 쉽게 구할 수 있는데, MySQL 에서는 이렇게 하려면 좀 까다롭다. Googling 해 보니 여러가지 방법이 있는데, 가장 간단한 방법은 group_concat Function을 사용하는 것 같다.
-- PROJECT_ID 별로 HISTORY_NO 값이 가장 큰 레코드를 추출하는 쿼리.
SELECT M.PROJECT_ID, E.*
FROM ORDER_SHEET E JOIN (
SELECT
K.PROJECT_ID,
SUBSTRING_INDEX ( group_concat(e.HISTORY_NO order by e.HISTORY_NO DESC), ',', 1) AS HISTORY_NO
FROM ORDER_SHEET E
JOIN LAB_HISTORY G ON E.HISTORY_NO = G.HISTORY_NO
JOIN PROJECT_INFO K ON G.PROJECT_NO = K.PROJECT_NO
WHERE E.USE_YN = 'Y' AND G.USE_YN='Y' AND K.USE_YN = 'Y'
GROUP BY K.PROJECT_ID) M
ON E.HISTORY_NO = M.HISTORY_NO;
HISTORY_NO 컬럼값 외에 다른 컬럼값을 가져오기 위해서는 Self Join을 한번 해야한다.
그런데 위처럼 ORDER BY 해서 가장 큰 값만 필요하다면 그냥 MAX() 를 써도 된다.
-- PROJECT_ID 별로 HISTORY_NO 값이 가장 큰 레코드를 추출하는 쿼리.
SELECT M.PROJECT_ID, E.*
FROM ORDER_SHEET E JOIN (
SELECT
K.PROJECT_ID,
MAX(e.HISTORY_NO) AS HISTORY_NO
FROM ORDER_SHEET E
JOIN LAB_HISTORY G ON E.HISTORY_NO = G.HISTORY_NO
JOIN PROJECT_INFO K ON G.PROJECT_NO = K.PROJECT_NO
WHERE E.USE_YN = 'Y' AND G.USE_YN='Y' AND K.USE_YN = 'Y'
GROUP BY K.PROJECT_ID) M
ON E.HISTORY_NO = M.HISTORY_NO;
그냥 MAX() 쓰면 되는데, 이제까지 뭐 한 거지... 쩝.
[참고]
Using LIMIT within GROUP BY to get N results per group?
http://stackoverflow.com/questions/2129693/using-limit-within-group-by-to-get-n-results-per-group
SQL: selecting top N records per group
http://code.openark.org/blog/mysql/sql-selecting-top-n-records-per-group
Rank function in MySQL
While the most upvoted answer ranks, it doesn't partition, You can do a self Join to get the whole thing partitioned also:
SELECT a.first_name,
a.age,
a.gender,
count(b.age)+1 as rank
FROM person a left join person b on a.age>b.age and a.gender=b.gender
group by a.first_name,
a.age,
a.gender
Use Case
CREATE TABLE person (id int, first_name varchar(20), age int, gender char(1));
INSERT INTO person VALUES (1, 'Bob', 25, 'M');
INSERT INTO person VALUES (2, 'Jane', 20, 'F');
INSERT INTO person VALUES (3, 'Jack', 30, 'M');
INSERT INTO person VALUES (4, 'Bill', 32, 'M');
INSERT INTO person VALUES (5, 'Nick', 22, 'M');
INSERT INTO person VALUES (6, 'Kathy', 18, 'F');
INSERT INTO person VALUES (7, 'Steve', 36, 'M');
INSERT INTO person VALUES (8, 'Anne', 25, 'F');
Answer:
Bill 32 M 4
Bob 25 M 2
Jack 30 M 3
Nick 22 M 1
Steve 36 M 5
Anne 25 F 3
Jane 20 F 2
Kathy 18 F 1
'Database > MySQL' 카테고리의 다른 글
[MySQL] Group 별로 순위 매기기 (0) | 2015.10.06 |
---|---|
[MySQL] rownum 사용하기 (0) | 2015.10.05 |
Mac 에서 MySQL 실행하기. 한글깨짐 현상 방지. (0) | 2015.04.20 |
[MySQL] Mac OS X 에서 실행 에러. The server quit without updating PID file (/usr/local/mysql/data/***.local.pid) (0) | 2015.04.15 |
[MySQL] NOW(), SYSDATE()의 차이점 (0) | 2015.04.01 |