출처| https://www.youtube.com/watch?v=UVY0mfa4VP0&list=PLqTUMsvO70nk8WfCyU-IPmc85390CaSqM&index=1
https://cafe.naver.com/thisisMySQL
https://velog.io/@ong_hh/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B5%AC%EC%B6%95
피벗 : 한 열에 포함된 여러 값을 출력하고, 이를 여러 열로 변환하여 테이블 반환 식을 회전하고 필요하면 집계까지 수행하는 것.
USE sqldb;
CREATE TABLE pivotTest
( uName CHAR(3),
season CHAR(2),
amount INT );
INSERT INTO pivotTest VALUES
('김범수','겨울',10), ('윤종신','여름',15) ;
SELECT * FROM pivoitTest;
SELECT uName,
SUM(IF(season='봄',amount,0)) AS '봄',
SUM(IF(season='여름',amount,0)) AS '여름',
SUM(IF(season='가을',amount,0)) AS '가을',
SUM(IF(season='겨울',amount,0)) AS '겨울',
SUM(amount) AS '합계' FROM pivotTest GROUP BY uName;
-- 김범수로 묶임(uName)으로 묶인다.
JSON데이터 : 현대의 웹가 모바일 응용 프로그램 등과 데이터를 교환하기 위한 개방형 표준 포맷.
속성과 값으로 쌍을 이루는 것을 확인할 수 있다.
USE sqldb;
SELECT JSON_OBJECT('name',name,'height',height) AS 'JSON 값'
FROM usertbl
WHERE height >= 180;
SET @json='{"usertbl" :
[
{"name":"임재범","height":182},
{"name":"이승기","height":182},
{"name":"성시경","height":186}
]
}';
SELECT JSON_VALID(@json) AS JSON_VALID;
SELECT JSON_SEARCH(@json, 'one','성시경') AS JSON_EXTRACT; -- 첫번째로 나오는 성시경을 찾아라, one과 all이 있음
SELECT JSON_EXTRACT(@json,'$.usertbl[2].name') AS JSON_EXTRACT;
SELECT JSON_INSERT(@json, '$usertbl[0].mDate','2009-09-09') AS JSON_INSERT;
SELECT JSON_REPLACE(@json,'$.usertbl[0].name', '홍길동') AS JSON_REPLACE; -- 0번째 name을 바꿈
SELECT JSON_REMOVE(@json,'$.usertbl[0]') AS JSON_REMOVE;
물건을 배송하기 위해 구매한 회원의 주소와 이 회원의 주소 정보를 알기 위해 주소 정보가 있는 회원 테이블과 결합하는 것 : INNER JOIN
SELECT <열 목록>
FROM <첫 번째 테이블>
INNER JOIN <두 번째 테이블>
ON <조인될 조건>
[WHERE 검색조건]
👇
USE sqldb;
SELECT *
FROM buytbl
INNER JOIN usertbl
ON buytbl.userID = usertbl.userID
WHERE buytbl.userID = 'JYP';
ON
으로 조건을 준다. 구매 테이블의 userID인 'JYP'를 추출하고 'JYP'와 동일한 값을 회원 테이블의 userID열에서 검색한 후 'JYP'라는 아이디를 찾으면 구매 테이블과 회원 테이블의 두 행을 결합(JOIN)한다.
MySQL 8.0.16 버전까지는 맨 아랫줄에 ORDER BY num 구문을 넣지 않아도 buytbl의 num열에 의해서 정렬되었으나 MySQL 8.0.17버전에서는 ORDER BY num 구문을 넣지 않으면 userID열로 정렬된다.
USE sqldb;
SELECT *
FROM buytbl
INNER JOIN usertbl
ON buytbl.userID = usertbl.userID
ORDER BY num;
이렇게 정렬되어 나타난다. 열의 항목이 너무 많아서 필요한 열만 추출하는 예제를 보자.
[열을 골라와서(아이디/이름/구매물품/주소/연락처 만) 뽑고 싶음]
SELECT userID, name, prodName, addr, CONCAT(mobile, mobile2) AS '연락처'
FROM buytbl
INNER JOIN usertbl
ON buytbl.userID = usertbl.userID
ORDER BY num;
위처럼 코드를 작성한다면, 에러가 뜬다.
구매테이블열도 userID열이 있고 회원테이블에도 userID열이 있다. 테이블 두 개에 같은 열 이름이 있어서 userID가 어느쪽 열인지 알 수 없다는 오류 메시지가 뜬다.
SELECT buytbl.userID, name, prodName, addr, CONCAT(mobile, mobile2) AS '연락처'
FROM buytbl
INNER JOIN usertbl
ON buytbl.userID = usertbl.userID
ORDER BY num;
따라서 위처럼 buytbl.userID라 써서 어느 테이블에 있는 userID를 쓰는지 명시해줘야 한다.
테이블 명을 앞에다가 다 붙여주는 것이 더 안전하지만, 코드가 너무 길어질 수 있다.
이를 간편하게 하기 위해서 각 테이블에 별칭
을 줄 수 있다.
SELECT B.userID, U.name, B.prodName, U.addr, CONCAT(mobile, mobile2) AS '연락처'
FROM buytbl B
INNER JOIN usertbl U
ON B.userID = U.userID
ORDER BY num;
table다음에 띄우고 별칭을 써주면 된다.
전체 회원 중 물품을 구매한 회원을 선별해보자.
SELECT DISTINCT U.userID, U.name, U.addr
FROM usertbl U
INNER JOIN buytbl B
ON U.userID = B.userID
ORDER BY U.userID;
'다대다(many-to-many)'의 관계이다.
다대다 관계는 논리적으로는 구성이 가능하지만 이를 물리적으로 구성하기 위해서는 두 테이블의 사이에 연결 테이블을 둬서 이 연결 테이블과 두 테이블이 일대다 관계를 맺도록 구성해야 한다.
SELECT S.stdName, S.addr, SC.clubName, C.roomNo
FROM stdtbl S
INNER JOIN stdclubtbl SC
ON S.stdName = SC.stdName
INNER JOIN clubtbl C
ON SC.clubName = SC.stdName
ORDER BY S.stdName;
첫번째 INNER JOIN한 결과를 가지고 다시 두번째 INNER JOIN을 하게 되는 것
use sqldb;
create table stdtbl
(
stdName varchar(10) NOT NULL PRIMARY KEY,
addr char(4) not null
);
create table clubtbl
(
clubName varchar(10) not null primary key,
roomNo char(4) not null
);
create table stdclubtbl
( num int auto_increment not null primary key,
stdName varchar(10) not null,
clubName varchar(10) not null,
foreign key(stdName) references stdtbl(stdName),
foreign key(clubName) references clubtbl(clubName)
);
insert into stdtbl values ('김범수','경남'), ('성시경', '서울'), ('조용필', '경기'), ('은지원', '경북'), ('바비킴','서울');
insert into clubtbl values ('수영', '101호'), ('바둑', '102호'), ('축구','103호'),('봉사','104호');
insert into stdclubtbl values (null, '김범수', '바둑'), (null, '김범수', '축구'), (null, '조용필', '축구'), (null, '은지원', '축구'), (null, '은지원', '봉사'), (null,'바비킴','봉사');
select S.stdName, S.addr, SC.clubName, C.roomNo
from stdtbl S
inner join stdclubtbl SC
ON S.stdName = SC.stdName -- 이너 조인을 한 결과를 가지고 밑에 inner join 시작한다.
inner join clubtbl C
ON SC.clubName = C.clubName
order by S.stdName;
select C.clubName, C.roomNo, S.stdName, S.addr
from stdtbl S
inner join stdclubtbl SC
ON SC.stdName = S.stdName
inner join clubtbl C
ON SC.clubName = C.clubName
order by C.clubName;
select S.stdName, S.addr, SC.clubName, C.roomNo
from stdtbl S
inner join stdclubtbl SC
ON S.stdName = SC.stdName -- 이너 조인을 한 결과를 가지고 밑에 inner join 시작한다.
inner join clubtbl C
ON SC.clubName = C.clubName
order by S.stdName;
select C.clubName, C.roomNo, S.stdName, S.addr
from stdtbl S
inner join stdclubtbl SC
ON SC.stdName = S.stdName
inner join clubtbl C
ON SC.clubName = C.clubName
order by C.clubName;
조인의 조건에 만족되지 않는 행까지도 포함시키는 것
SELECT <열 목록>
FROM <첫 번째 테이블(LEFT 테이블)>
<LEFT | RIGHT | FULL> OUTER JOIN <두 번째 테이블(RIGHT 테이블)>
ON <조인될 조건>
[WHERE 검색조건] ;
전체 회원 출력시 사용.
use sqldb;
select U.userID, U.name, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
from usertbl U
LEFT OUTER JOIN buytbl B -- 왼쪽 테이블의 것은 모두 출력되어야 한다.(usertbl)
ON U.userID = B.userID
ORDER BY U.userID;
INNER JOIN의 활용 중에서 구매한 기록이 있는 우수 회원들의 목록만 뽑아 봤지만, 이번엔 한 번도 구매한 적이 없는
유령 회원의 목록을 뽑아보자.
use sqldb;
select U.userID, U.name, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
from usertbl U
LEFT OUTER JOIN buytbl B -- 왼쪽 테이블의 것은 모두 출력되어야 한다.(usertbl)
ON U.userID = B.userID
where B.prodName IS NULL
ORDER BY U.userID;
예시2
SELECT S.stdName, S.addr, C.clubName, C.roomNo
FROM stdtbl S
LEFT OUTER JOIN stdclubtbl SC
ON SC.stdName = S.stdName
RIGHT OUTER JOIN clubtbl C
ON SC.clubName = C.clubName
ORDER BY S.stdName;
SELECT C.clubName, C.roomNo, S.stdName, S.addr
FROM stdtbl S
LEFT OUTER JOIN stdclubtbl SC
ON SC.stdName = S.stdName
RIGHT OUTER JOIN clubtbl C
ON SC.clubName = C.clubName
ORDER BY C.clubName;
UNION
SELECT S.stdName, S.addr, C.clubname, C.roomNo
FROM stdtbl S
LEFT OUTER JOIN stdclubtbl SC
ON SC.stdName = S.stdName
RIGHT OUTER JOIN clubtbl C
ON SC.clubName = C.clubName;
문법 및 많은 예시는 이 블로그를 참조하자.
USE sqldb;
SELECT *
FROM buytbl
CROSS JOIN usertbl;
샘플데이터 만들 때 종종 사용한다.
별도의 구문이 있는 것이 아니라 자기 자신과 자기 자신이 조인한다는 의미.
USE sqldb;
SELECT *
FROM buytbl A
INNER JOIN buytbl B
ON A.userID = B.userName
WHERE A.userID = 'JYP';
같은 테이블인데 별칭을 다르게 하면서 씀.
두 쿼리의 결과를 합친 것
UNION : 중복된 열은 제거
UNION ALL : 중복된 열까지 모두 출력
NOT IN : 뒤의 내용을 빼고 출력
IN : 첫 번째 쿼리의 결과 중에서, 두 번째 쿼리에 해당되는 것만 조회