[13일차] 서브 쿼리, 사용자계정(작성중)
2026. 6. 8. 22:44ㆍKDT/2. MySQL
1. 서브쿼리 Sub Query
- SQL문 안에 들어가는 또 다른 SELECT문
- 예시
-- 김사과보다 포인트가 많은 회원을 검색
select point from member where name = '김사과';
select * from member where point > 150;
-- 서브쿼리를 사용하여 한 번에 작성
select * from member where point > (select point from member where name = '김사과');
1. 단일 행 서브쿼리
- 결과가 하나의 값만 나오는 서브쿼리
-- 포인트가 가장 높은 회원 검색
select * from member where point = (select max(point) from member);
-- 서브쿼리만 실행해보면 max(point)가 250인 것 확인 가능
select max(point) from member;
2. 다중 행 서브쿼리
- 결과가 여러 개 나오는 서브쿼리
- in, any, all을 사용
-- 포인트가 200 이상인 userid 목록에 포함된 회원 검색
select * from member where userid in (select userid from member where point >= 150);
3. from 절 서브쿼리
- 서브쿼리 결과를 임시 '테이블'처럼 사용하는 방식
-- 포인트가 150 이상인 회원의 이름과 포인트를 조회
select name, point from (select name, point from member where point >= 150) as high_point_member;
-- from 절 서브쿼리를 조회하면 테이블 형태로 나올 것
select name, point from member where point >= 150;
4. select 절 서브쿼리
- 조회 결과에 서브쿼리 결과를 함께 보여주는 방식
-- 각 회원의 포인트와 전체 평균 포인트를 함께 검색
select name, (select avg(point) from member) as avg_point from member;
5. exists 서브쿼리
- 존재 여부를 확인할 때 사용
- 아래 orders 예제를 모두 푼 후 다시 보자
-- 주문 내역이 있는 회원을 검색
select * from member m where exists (select 1 from orders o o.member_idx = m.idx);
-- select 1 : 하나라도 존재하는지 확인
# 예제를 풀어보자
- orders 테이블 생성 후 데이터 삽입
-- orders 테이블 생성
create table orders (
order_id int auto_increment primary key,
member_idx int not null,
product_name varchar(100) not null,
price int not null,
order_date datetime default now(),
foreign key (member_idx) references member(idx)
);
-- 데이터 삽입
insert into orders(member_idx, product_name, price)
values
(1, '키보드', 50000),
(1, '마우스', 30000),
(2, '모니터', 250000),
(2, '노트북 거치대', 40000),
(3, 'USB', 15000),
(4, '노트북', 1200000),
(4, '헤드셋', 90000);
-- 잘 만들어졌는지 확인
select * from orders;
- 예제를 풀어보자
-- 1. 주문한 적이 있는 회원들만 조회
select * from member where idx in (select member_idx from orders);
-- 2. 주문한 적이 없는 회원들만 조회
select * from member where idx not in (select member_idx from orders);
-- 3. 가장 비싼 상품을 주문한 회원 조회
select * from member where idx = (select member_idx from orders where price = (select max(price) from orders));
-- 4. 가장 비싼 상품을 주문한 회원의 이름과 상품명, 가격을 조회
select m.name, o.product_name, o.price from member as m left join orders as o on m.idx = o.member_idx
where o.price = (select max(price) from orders);
-- 4번 처음 풀 때, 아래처럼 만들었는데 결과는 같음
select m.name, o.product_name, o.price
from member as m left join orders as o on m.idx = o.member_idx
where idx = (
select member_idx from orders where price = (select max(price) from orders)
)
order by o.price desc limit 1;
6. 서브쿼리로 스키마와 테이블 복사
- orders 스키마를 복사해와서 orders_copy 스키마 생성
-- orders 테이블 형태만 복사
create table orders_copy (
order_id int auto_increment primary key,
member_idx int not null,
product_name varchar(100) not null,
price int not null,
order_date datetime default now(),
foreign key (member_idx) references member(idx)
);
-- 형태만 복사했으니 데이터는 없는 상태
select * from orders_copy;
- 서브쿼리를 사용하여 orders 테이블의 데이터를 orders_copy로 복사 (테이블 형태가 똑같아야 가능)
-- 서브쿼리로 데이터 복사
insert into orders_copy (select * from orders);
-- 잘 복사되었는지 확인
select * from orders_copy;
2. UNION
- 여러 개의 select 결과를 하나로 합쳐주는 기능
- 조회 결과를 위 아래로 이어 붙이는 기능
- 중복 데이터 제거
- union all : 중복 데이터 제거하지 않음
- 서울 회원과 부산 회원 합치기
select name, address1 from member where address1 like '서울%' -- 서울 회원
union
select name, address1 from member where address1 like '부산%'; -- 부산 회원
- 새로운 voca_new 테이블 생성 후, 데이터 삽입하고 잘 들어갔는지 확인
-- voca_new 테이블 생성
create table voca_new (
eng varchar(50) primary key,
kor varchar(50) not null,
lev int default 1,
regdate datetime default now()
);
-- 데이터 삽입
insert into voca_new values('pineapple', '파인애플', 2, now());
insert into voca_new values('papaya', '파파야', 2, now());
insert into voca_new values('blueberry', '블루베리', 1, now());
-- 잘 들어갔는지 확인
select * from voca_new;
- voca의 eng, kor, lev와 voca_new의 eng, kor, lev를 조회
select eng, kor, lev from voca
union
select eng, kor, lev from voca_new;
- 겹치는 데이터 사과 추가 후 다시 union 해보자
-> 중복되는 데이터는 보이지 않는 것이 확인 가능
insert into voca_new values('apple', '사과', 1, now());
select eng, kor, lev from voca union select eng, kor, lev from voca_new;
- 그렇다면 voca와 voca_new의 eng, kor, lev, regdate를 모두 조회
-> regdate는 다르기 때문에 중복 데이터가 아니라 사과가 2개가 조회됨
select eng, kor, lev, regdate from voca union select eng, kor, lev, regdate from voca_new;
- 중복데이터를 제거하지 않고 조회
select eng, kor, lev from voca union all select eng, kor, lev from voca_new;
3. 사용자 계정
- 데이터베이스에 접속할 수 있는 로그인 계정
- root 계정은 모든 권한을 가진 계정이기 때문에 실제 사용 시 위험할 수 있음
- 프로젝트 별로 계정을 따로 만들고 필요한 권한만 부여하는 것이 일반적
1. 계정 생성
| create user '계정명'@'접속위치' identified by '비밀번호'; |
- localhost : 같은 컴퓨터(내 컴퓨팅)에서만 접속
- 'apple'@'%' : 어디서든 접속 가능
- 'apple'@'192.168.0.%' : 192.168.0.으로 시작하는 내부망에서만 접속 가능
- 'apple'@' 192.168.0.10' : 특정 ip에서만 접속 가능
-- apple이라는 계정을 만들고 비밀번호는 1111, localhost로 접속하도록 계정 만들기
create user 'apple'@'localhost' identified by '1111';
2. 권한 부여 및 확인
| 권한 부여 | grant 권한종류 on 데이터베이스명.테이블명 to '계정명'@'접속위치'; |
| 권한 확인 | show grants for '계정명'@'접속위치'; |
- all : 모든 일반 권한. select, insert, update, delete, create, drop, alter, index
- ai.* : ai 데이터베이스 안의 모든 테이블
- *.* : 모든 데이터베이스 안의 모든 테이블
- ai.member : ai 데이터베이스 안의 member 테이블
- apple, banana, orange 계정 생성 후 아래와 같이 권한 부여
- apple : 모든 권한
- banana : select 권한만
- orange : select, insert, update, delete 권한
-- apple 계정에 모든 권한 부여
grant all on ai.* to 'apple'@'localhost';
-- 권한 확인
show grants for 'apple'@'localhost';
-- banana 계정 생성 후 select 권한만 부여
create user 'banana'@'localhost' identifited by '2222';
grant select on ai.* to 'banana'@'localhost';
-- orange 계정 생성 후 select, insert, update, delete 권한 부여
create user 'orange'@'localhost' identified by '3333';
grant select, insert, update, delete on ai.* to 'orange'@'localhost';
- apple, banana, orange 계정으로 로그인해보고 파일 만들어보기
-- 김사과.sql
use ai;
show databases;
show tables;
select * from member;
-- root 계정이 아닌 다른 계정에서는 create user 불가능
-- create user 'banana'@'localhost' identified by '2223';
3. 권한 회수하기
4. 사용자 비밀번호 변경하기
# ip 주소란
4. MySQL 함수
1. 문자열 함수
2. 수학 함수
3. 날짜 함수
4. 조건 함수
5. 형변환 함수
6. 집계 함수
'KDT > 2. MySQL' 카테고리의 다른 글
| [14일차-1] 뷰 (0) | 2026.06.09 |
|---|---|
| [12일차] SQL문 연산자, 정규화 (0) | 2026.06.07 |
| [11일차] MySQL, SQL명령어(DDL, DML) (0) | 2026.06.04 |