'셀프조인'에 해당되는 글 1건

[MySQL] Self Join 예제

SQL 2016. 2. 22. 15:19
728x90

네이버지식인에 올라온 셀프조인 문의사항이 있어서 작성해봤다.

 

먼저 테이블 구조 및 데이터는

CREATE TABLE IF NOT EXISTS `tb1` (
  `number` varchar(5) NOT NULL,
  `name` varchar(10) NOT NULL,
  `age` int(5) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `tb1` (`number`, `name`, `age`) VALUES
('A101', '강신우', 40),
('A102', '김기덕', 28),
('A103', '김민호', 20),
('A104', '문소리', 23),
('A105', '박문수', 35);

 

윈도우버전 AutoSet9 에서 테스트를 해봤다.

 

이 화면에

SELECT a.name , a.age, COUNT(*)
FROM tb1 AS a JOIN tb1 AS b
WHERE a.age <=b.age
GROUP BY a.number;

쿼리문을 넣고 실행을 누른다.

그러면 결과를 다음과 같이 보여준다.

 

 

Join 의 개념을 모를때는 참 어렵게 생각했는데 알고보면 아무것도 아니다.

Join 은 그냥 물리적인 테이블 2개를 마치 1개처럼 생각하고 쿼리문을 만드는 거라고 생각하면 참 쉽다.

Self 조인은 하나의 물리적인 테이블을 가지고 2개의 가상테이블처럼 만들어서 원하는 결과를 조회하는 것이다.

원하는 결과를 도출하기 위해서 물리적인 테이블을 계속 생성하는 것 대신에 메모리상에서 논리적인 테이블을 만들어서 결과를 뽑아내는 거라고 보면 된다.

경우에 따라서는 물리적인 테이블을 생성해서 결과를 찾는 것이 빠를 수도 있다.

이 테이블에는 Index 가 설정되어 있지 않고 간단하게 Join 의 개념만 알고 싶은 것이라고 이해하면 된다.

 

SELECT a.number, a.name , a.age, b.number, b.name , b.age
FROM tb1 AS a JOIN tb1 AS b;

이 쿼리문은 가상 테이블 2개를 조인하는데 서로 공통의 분모에 해당하는 조건이 없는 경우다.

즉, 데이타가 5개 들어있다면 5 X 5 = 25 개의 결과를 보여준다.

 

 

여기서 데이터 정렬를 number 필드 기준으로 하고 싶다면 ORDER by a.number 를 추가하면 된다.

number 가 아닌 a.number 를 한 이유는 가상테이블 a 와 가상테이블 b 중에서 어떤 테이블을 기준으로 정렬할 것인가를 정해주는 것이기 때문이다.

 

 

이제 처음에 했던 쿼리문을 다시 해보자.

SELECT a.name , a.age, COUNT(*)
FROM tb1 AS a JOIN tb1 AS b
WHERE a.age <=b.age
GROUP BY a.number;
왜 a.age <= b.age 라고 했는지 위의 결과가 나온 그림을 보면 이해가 될 것이다.

 

그래도 이해가 안되면

SELECT a.number, a.name , a.age, COUNT(*)
FROM tb1 AS a JOIN tb1 AS b
GROUP BY a.number;
와 같이 Where 조건절을 빼고 조회를 해본다. 대신 a.number 칼럼을 추가해서 조회를 해준다.

 

이걸 보면 구하려고 하는 결과를 얻기 위해서 Where 조건을 왜 이렇게 해야 되는지 이해가 될 것이다.

 

phpMyAdmin 상에서 내가 해보고 싶은 Select 쿼리문을 만들어서 테스트를 해보고 원하는 결과가 나오는지 확인하면 정말 편하다.

 

SELECT a.name , a.age, COUNT(*)
FROM tb1 AS a JOIN tb1 AS b ON a.age <=b.age
GROUP BY a.number;

SELECT a.name , a.age, COUNT(*)
FROM tb1 AS a JOIN tb1 AS b
WHERE a.age <=b.age
GROUP BY a.number;

SELECT a.name , a.age, COUNT(*)
FROM tb1 a, tb1 b
WHERE a.age <=b.age
GROUP BY a.number;

 

동일한 결과를 보여주는 쿼리문이다. 첫번째는 ANSI Join 이고 마지막 것은 오라클 방식의 Join 이다.

모두 MySQL 에서 지원한다.

개인적으로는 오라클 방식의 조인이 편하다.

FROM 테이블 표시되는 부분에서 가독성이 더 좋다. 테이블을 여러개 조인할 때도 편하다.

 

'SQL' 카테고리의 다른 글

엑셀에서 INSERT 쿼리문 만들기  (0) 2016.07.29
조건별 SUM SQL  (0) 2016.07.27
[MySQL] order by 정렬  (0) 2016.01.26
MySQL Update Where 조건절 Subquery  (1) 2016.01.22
MySQL 테이블간 참조무결성  (0) 2015.09.28
블로그 이미지

Link2Me

,