kok202
MySQL 특정 칼럼에 중복 제거된 값으로 페이징하기

2019. 5. 10. 15:36[정리] 데이터베이스/[RDBMS] MySQL

DROP TABLE item;

CREATE TABLE item
(
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(200),
  first_seen BIGINT,
  group_id BIGINT
);

INSERT INTO item(name, first_seen, group_id) VALUES("A", 15100, 1);
INSERT INTO item(name, first_seen, group_id) VALUES("B", 15654, 2);
INSERT INTO item(name, first_seen, group_id) VALUES("C", 46812, 3);
INSERT INTO item(name, first_seen, group_id) VALUES("D", 15412, 4);
INSERT INTO item(name, first_seen, group_id) VALUES("E", 17213, 5);
INSERT INTO item(name, first_seen, group_id) VALUES("F", 15234, 6);
INSERT INTO item(name, first_seen, group_id) VALUES("G", 12534, 1);
INSERT INTO item(name, first_seen, group_id) VALUES("H", 10564, 1);
INSERT INTO item(name, first_seen, group_id) VALUES("I", 15342, 2);
INSERT INTO item(name, first_seen, group_id) VALUES("J", 15213, 2);
INSERT INTO item(name, first_seen, group_id) VALUES("K", 32341, 7);
INSERT INTO item(name, first_seen, group_id) VALUES("L", 15643, 8);
INSERT INTO item(name, first_seen, group_id) VALUES("M", 14521, 9);
INSERT INTO item(name, first_seen, group_id) VALUES("N", 14254, 10);
INSERT INTO item(name, first_seen, group_id) VALUES("O", 15372, 10);
INSERT INTO item(name, first_seen, group_id) VALUES("P", 14983, 11);
INSERT INTO item(name, first_seen, group_id) VALUES("Q", 14464, 12);
INSERT INTO item(name, first_seen, group_id) VALUES("R", 15654, 13);
INSERT INTO item(name, first_seen, group_id) VALUES("S", 15321, 14);
INSERT INTO item(name, first_seen, group_id) VALUES("T", 15215, 15);
INSERT INTO item(name, first_seen, group_id) VALUES("U", 15045, 16);
INSERT INTO item(name, first_seen, group_id) VALUES("V", 15622, 17);
INSERT INTO item(name, first_seen, group_id) VALUES("W", 14896, 18);
INSERT INTO item(name, first_seen, group_id) VALUES("X", 16545, 19);
INSERT INTO item(name, first_seen, group_id) VALUES("Y", 15342, 20);
INSERT INTO item(name, first_seen, group_id) VALUES("Z", 34512, 19);
INSERT INTO item(name, first_seen, group_id) VALUES("AA", 14867, 1);

select * from item;


# 문제 : 그룹 단위가 아니다.
# item 가 그룹 단위의 first_seen 이 가장 빠른 순서대로 페이징 하고 싶다.
# 더불어 데이터는 그룹이 여러개 중복되면 안되게 하고싶다.
select *
from item 
order by first_seen asc
limit 10 offset 0;



# try 1 : distinct 를 써보자
# 문제 : first_seen 정보가 없어서 정렬이 안된다.
select distinct group_id
from item 
order by first_seen asc
limit 10 offset 0;



# try 2 : distinct 를 써보자
# 문제 : distinct 가 (group_id, first_seen) 에 걸려서 의미가 없어진다.
select distinct group_id, first_seen
from item 
order by first_seen asc
limit 10 offset 0;



# 정보 1 : MySQL은 distinct only one column 을 지원하지 않는다.
# 정보 2 : 문제의 상황의 경우 그룹핑을 하고 싶은거니까 Group by 를 쓰는 것이 맞다.
# 문제 : Group by 를 쓸  String 은 어떤 값으로 표기할지 애매해진다.
# 해결 : ANY_VALUE 를 쓰면 된다.
# 1차 해결
select ANY_VALUE(id), min(first_seen) as first_seen, ANY_VALUE(name), group_id
from item 
group by group_id
order by first_seen asc
limit 10 offset 0;



# 문제 : ANY_VALUE 가 마음에 안든다.
# 일단 레코드를 가져온 다음에 서버 사이드에서 원하는 데이터 집어넣자.
# ANY_VALUE를 삭제
select min(first_seen) as first_seen, group_id
from item 
group by group_id
order by first_seen asc
limit 10 offset 0



# 결론(?)
# 정보 1 : MySQL 은 Sub query 를 쓸 때 alias를 줘야한다.
select *
from item
where group_id in
(
	select group_id from
	(
		select min(first_seen) as first_seen, group_id
		from item 
		group by group_id
		order by first_seen asc
		limit 10 offset 0
	)as subQuery
);

 

문제 상황의 키워드는 '중복 제거' 가 아니라 '그룹핑' 이다.

 

 

 

'[정리] 데이터베이스 > [RDBMS] MySQL' 카테고리의 다른 글

MySQL Read ISOLATION  (0) 2020.01.03
터미널 기본  (0) 2019.01.23