SELECT * FROM titles; -- titles 테이블에서 모든 열의 내용을 가져와라.
SELECT * FROM employees.titles;
SELECT * FROM titles;
--둘다 동일한 결과값이다.
SELECT first_name FROM employees --employees의 DB에서 first_name열만 가져온다.
여러개의 열을 가지고 오고 싶으면 콤마(,)로 구분하면 됨.
SELECT first_name,last_name,gender FROM employees;
--employees DB에서 first_name,last_name,gender만 출력.
[실습1.db이름,테이블이름,필드 이름이 정확히 기억나지 않거나 이름이 철자가 확실하지 않을때 조회하는 방법!] 조회하고자 하는 내용이 employees 데이터베이스에 있는 employees 테이블의 first_name 및 gender 열. ①일단 서버에 어떤 데이터베이스가 있는지 조회해보자.
SHOW databases;
②DB이름이 employees이니, 이제 테이블 이름을 알아보기 위해 테이블 정보를 조회합시다.
SHOW tables;
③employees 테이블의 열에 뭐가 있는지 확인해볼까!
describe employees;
여기서 first_name과 gender를 확인했다. ④최종적으로 데이터를 조회한다.
select first_name, gender from employees;
where문 : 조건을 지정하기! [실습2 : 새로운 db를 만듭니다..] ①일단 DB를 만듭니다. 이건 sqldb라는 이름의 데이터베이스가 있으면 삭제 후 sqldb를 만드는 것.
DROP DATABASE IF EXISTS sqldb;
create database sqldb;
②다음처럼 테이블을 만들어봅시다
use sqldb;
create table usertbl
( userID char(8) not null primary key,
name varchar(10) not null,
birthYear int not null,
addr char(2) not null,
mobile1 char(3),
mobile2 char(8),
height smallint,
mDate date
);
create table buytbl
( num int auto_increment not null primary key,
userID char(8) not null,
prodName char(6) not null,
groupName char(4),
price int not null,
amount smallint not null,
foreign key (userID) references usertbl(userID)
);
※ 주의 : SQL은 { } 가 아니라 ( ) 입니다 > 이거때문에 오류났었음 ㅠㅠ
③테이블 내에 데이터를 입력하고 확인도 합시다.
INSERT INTO usertbl values('LSG','이승기','1987','서울','011','11111111',182,'2008-8-8');
INSERT INTO usertbl values('KBS','김범수','1979','경남','011','22222222',173,'2012-4-4');
INSERT INTO usertbl values('KKH','김경호','1971','전남','019','33333333',177,'2007-7-7');
INSERT INTO usertbl values('JYP','조용필','1950','경기','011','4444444',166,'2009-4-4');
INSERT INTO usertbl values('SSK','성시경','1979','서울',NULL,NULL,186,'2013-12-12');
INSERT INTO usertbl values('LJB','임재범','1963','서울','016','66666666',182,'2009-9-9');
INSERT INTO usertbl values('YJS','윤종신','1969','경남',NULL,NULL,170,'2005-5-5');
INSERT INTO usertbl values('EJW','은지원','1972','경북','011','88888888',174,'2014-3-3');
INSERT INTO usertbl values('JKW','조관우','1965','경기','018','99999999',172,'2010-10-10');
INSERT INTO usertbl values('BBK','바비킴','1973','서울','010','00000000',176,'2013-5-5');
INSERT INTO buytbl values(NULL,'KBS','운동화',NULL,30,2);
INSERT INTO buytbl values(NULL,'KBS','노트북','전자',1000,2);
INSERT INTO buytbl values(NULL,'JYP','모니터','전자',200,1);
INSERT INTO buytbl values(NULL,'BBK','모니터','전자',200,5);
INSERT INTO buytbl values(NULL,'KBS','청바지','의류',50,3);
INSERT INTO buytbl values(NULL,'BBK','메모리','전자',80,10);
INSERT INTO buytbl values(NULL,'SSK','책','서적',15,5);
INSERT INTO buytbl values(NULL,'EJW','책','전자',15,2);
INSERT INTO buytbl values(NULL,'EJW','청바지','의류',50,1);
INSERT INTO buytbl values(NULL,'BBK','운동화',NULL,30,2);
INSERT INTO buytbl values(NULL,'EJW','책','서적',15,1);
INSERT INTO buytbl values(NULL,'BBK','운동화',NULL,30,2);
SELECT * FROM usertbl;
SELECT * FROM buytbl;
결과가 다음처럼 나온다.
SELECT ... FROM ... WHERE ... : 특정조건 데이터만 조회! 일단 sqldb를 택해서 usertbl을 본다.
USE sqldb;
SELECT * FROM usertbl;
'김경호'라는 이름을 검색해보자.
SELECT * FROM usertbl where name='김경호';
관계연산자 사용 1970년 이후에 출생, 신장이 182 이상인 사람의 아이디와 이름 조회해보기
select userID,name from usertbl where birthYear>=1970 and height>=182;
1970년 이후에 출생했거나, 신장이 182이상인 사람의 아이디와 이름 조회
select userID,name from usertbl where birthYear>=1970 or height>=182;
BETWEEN ... AND과 IN() 그리고 LIKE 키가 180~183인 사람을 조회해보자.
SELECT * FROM usertbl where height between 180 and 183;
SELECT * FROM usertbl where height >=180 and height <=183;
지역이 경북,전남,경북인 사람의 정보를 찾아보자. IN()은 이산적인 값을 위해 사용함!
select * from usertbl where addr='경남' or addr='전남'or addr='경북';
select name,addr from usertbl where addr in('경남','전남','경북');
'김'씨인 사람을 찾자. : LIKE > 문자열 내용 검색
select * from usertbl where name like '김%';
이외에도 '_용%'이면 앞에 아무거나 한글자, 두번째는 용, 세번째는 몇글자든 아무거나 오는값 추출
SELECT name,height FROM usertbl WHERE name LIKE '_용%';
결과는
ANY/ALL/SOME 그리고 서브쿼리(SubQuery,하위쿼리)
서브쿼리 : 쿼리문 내부의 쿼리문 ex.1.김경호보다 키가 크거나 같은 사람의 이름과 키를 출력하려면 where로 김경호 키를 써줘야함.
SELECT name,height FROM usertbl where height>177;
근데 177을 직접 써주는게 아니라 쿼리를 통해 작성하기!!!
SELECT name,height FROM usertbl
WHERE height > (SELECT height FROM usertbl WHERE name='김경호');
ex2.지역이 '경남'사람의 키보다 키가 크거나 같은 사람 추출
select name,height from usertbl where height >= (select height from usertbl where addr='경남');
이렇게 쓰면..
이런 오류가 난다. 하위쿼리가 2개이기 때문이다! 그래서 필요한 구문이 ANY 구문.
select name,height from usertbl where height >= any(select height from usertbl where addr='경남');
이때 실행하면 173보다 크거나 키가 170보다 크거나 같은 사람이 모두 출력됨 > 결국 170보다 크거나 같은 사람이 해당됨. any 대신 all로 바꿔 실행해보면..
select name,height from usertbl where height >= all(select height from usertbl where addr='경남');
173 이상이 출력된다. ANY는 여러개의 결과 중 하나만 만족해도 되고, ALL은 모두 만족해야함.
이번엔 >=ANY 대신 '=ANY'를 써보자.
select name,height from usertbl where height = any(select height from usertbl where addr='경남');
그러면 173,170에 해당되는 사람만 출력된다. 즉 '=ANY'(서브쿼리)는 'IN(서브쿼리)'와 동일한 것!!!!
ORDER BY : 결과가 출력되는 순서를 조절하는 구문.
오름차순 : ASC, 디폴트값.1→2→3→4
내림차순 : DESC, 4→3→2→1
먼저 가입한 순서로 회원들을 출력해보자.
SELECT name,mDate from usertbl order by mdate;
그러면 원래 이렇게 나온다. 기본적으론 오름차순 기준. 키가 큰 순서로 정렬하되, 키가 같은면 이름순으로 정렬하자.
SELECT name,height from usertbl order by height desc, name;
우선 테이블 이름 다음에 나오는 열은 생략 가능. 하지만 생략시 values 다음에 나오는 값들의 순서 및 개수가 테이블 정의 열순서 및 개수가 동일해야함
USE sqldb;
CREATE TABLE testtbl1(id int,userName char(3),age int);
INSERT INTO testtbl1 VALUES (1,'홍길동',25);
위에서 ID와 이름만을 입력하고 나이 입력을 안하고 싶으면 입력할 열의 목록을 나열해줘야함. 생략된 AGE에는 null임
INSERT INTO testtbl1(id,userName) VALUES(2,'설현');
AUTO_INCREMENT : 자동증가. 자동으로 1부터 증가하는 값을 입력해준다.
USE sqldb;
create TABLE testtbl2
(id int auto_increment PRIMARY KEY,
userName char(3),
age int);
insert into testtbl2 values(NULL,'지민',25);
insert into testtbl2 values(NULL,'유나',22);
insert into testtbl2 values(NULL,'유경',21);
select * from testtbl2;
select last_insert_id();
마지막에 입력된 값을 보여준다. 이 경우에는 3을 보여줌. 근데 이후에 100부터 입력되도록 변경하고 싶다면...
ALTER TABLE testtbl2 AUTO_INCREMENT=100;
INSERT INTO testtbl2 values(null,'찬미',23);
select * from testtbl2;
증가값을 지정하려면 서버변수인 @@auto_increment_increment변수를 변경시켜야함. 다음 예제는 초깃값을 1000으로 하고 증가값은 3으로 변경하는 예제.
USE sqldb;
create table testtbl3
(id int auto_increment primary key,
userName char(3),
age int);
alter table testtbl3 auto_increment=1000;
set @@auto_increment_increment=3;
insert into testtbl3 values(null,'나연',20);
insert into testtbl3 values(null,'정연',18);
insert into testtbl3 values(null,'모모',149);
select *from testtbl3;
대량의 샘플 데이터 생성 : 직접 키보드로 입력하려면 많은 시간이 걸림.
INSET INTO 테이블이름(열 이름1, 열이름2,....)
SELECT문 ;
예제... employees의 데이터를 가져올때..
USE sqldb;
CREATE TABLE testtbl4(id int,Fname varchar(50),Lname varchar(50));
INSERT INTO testtbl4
select emp_no,first_name,last_name from employees.employees;
데이터수정 : UPDATE - 기존에 입력되어있는 값을 변경하기 위함 형식은
UPDATE 테이블이름
SET 열1=값1, 열2=값2....
WHERE 조건;
WHERE절은 생략가능하지만 생략하면 테이블 전체의 행이 변경된다. testtbl4의 'Kyoichi'dml Lname을 '없음'으로 변경해보자. 원래 이랬는데,
update testtbl4 set Lname = '없음' where Fname='Kyoichi';
이렇게 바뀜. where 절이 없다면 전체행의 Lname이 모두 '없음'으로 변경됨.
* 전체 테이블의 내용을 변경하고 싶을때 where 생략가능.
ex)buytbl(구매테이블)의 현재 단가가 1.5배 인상됐다면...
원래 이상태였다면
update buytbl set price=price*1.5;
price가 1.5배 증가한 걸 확인할 수 있다!
데이터의 삭제 : DELETE FROM / 행단위로 삭제함
DELETE FROM 테이블이름 WHERE 조건; --형식
testtbl4에서 Aamer 사용자가 필요없다면 다음처럼 해보자.
delete from testtbl4 where Fname='Aamer';
만약 상위 몇건만 삭제하려면 LIMIT 구문을 함께 사용하면 된다.
delete from testtbl4 where Fname='Aamer' LIMIT 5;
대용량 테이블 삭제를 해볼까!
1.대용량 테이블 3개를 생성하자.
USE sqldb;
CREATE TABLE bigtbl1(select * from employees.employees);
CREATE TABLE bigtbl2(select * from employees.employees);
CREATE TABLE bigtbl3(select * from employees.employees);
이렇게 만들어지고 나서... delete, drop, truncate 문으로 세 테이블을 모두 삭제해보자.
delete from bigtbl1;
drop table bigtbl2;
truncate table bigtbl3;
① DELETE는 시간이 오래 걸림. DML문일므로, 트랜잭션 로그를 기록하는 작업때문에 오래 걸림
② DROP : 금방 끝남. 테이블자체를 삭제함. DDL문. 테이블 자체가 필요없을 경우.
③ TRUNCATE : DDL문. 금방끝남. DLELETE와 동일함. 트랜잭션 로그를 기록하지 않아서 속도가 무척 빠름. 테이블 구조는 남겨놓고 싶다면 이쪽으로.
조건부 데이터 입력,변경 1. 멤버테이블을 정의하고 데이터 입력. 기존 usertbl에서 아이디,이름,주소만 가져와서 간단히 만들자.
create table membertbl(select userID,name,addr from usertbl limit 3); -- 3건만 가져옴
alter table membertbl add constraint pk_membertbl primary key(userID); -- pk 지정
select * from membertbl;
2.데이터를 추가로 3건 입력하기. 근데 첫번째에서 PK를 중복 하는 실수를 했다.
insert into membertbl values('BBK','비비코','미국');
insert into membertbl values('SJH','서장훈','서울');
insert into membertbl values('HJY','현주엽','경기');
insert into membertbl values('BBK','비비코','미국') on duplicate key update name='비비코',addr='미국';
insert into membertbl values('DJM','동짜몽','일본') on duplicate key update name='동짜몽',addr='일본';
select * from membertbl;
첫번째 BBK는 중복이므로 UPDATE 수행이 됨. 두번째 입력한 DJM은 없으므로 INSERT처럼 데이터 됨.
두번째 DJM은 없으므로 일반적인 INSERT처럼 데이터 입력됨.
ON DUPLICATE KEY UPDATE는 PK 중복없으면 INSET, 중복되면 그 뒤의 UPDATE문이 수행됨.
WITH 절과 CTE - WITH 절 : CTE(Common Table Expression)를 표현하기 위한 구문/ 기존의 뷰, 파생테이블, 임시테이블 등으로 사용되던 것을 대신할 수 있음. 더 간결한 식으로 보여짐. - CTE : 비재귀적 CTE, 재귀적 CTE로 나뉨.
비재귀적 CTE : 재귀적이지 않은 CTE
WITHE CTE_테이블이름(열이름)
AS
(
<쿼리문>
)
SELECT 열 이름 FROM_테이블이름; -- 비재귀적CTE 형식
쉬운 이해를 위해 buytbl에서 총 구매액 구하기를 다시 살펴보자..
SELECT userID as '사용자', sum(price*amount) as '총구매액' from buytbl group by userid;
이 결과를 총 구매액이 많은 사용자 순서대로 정렬하고 싶다면..
①앞의 쿼리에 이어 ORDER BY문을 붙여도됨
②결과값 테이블이름이 abc라는 이름이면
select * from abc order by 총구매액 desc;
이런 느낌으로 더 간단해짐.
즉..
WITH abc(userid,total)
as
(select userID,sum(price*amount)
from buytbl group by userid)
select * from abc order by total desc;
이렇게 할 수 있단 소리임.
또다른 예시로 연습을 해보자.
회원테이블(usertbl)에서 각 지역별로 큰 키를 1명식 뽑고 그 사람들의 키 평균을 내보자.
①"각 지역별로 가장 큰 키"를 뽑는 쿼리
SELECT addr,max(height) from usertbl group by addr;
②이 쿼리를 WITH 구문으로 묶는다.
WITH cte_usertbl(addr,maxHeight)
as
(SELECT addr,max(height) from usertbl group by addr)
③키의 평균을 구하는 쿼리를 작성한다.
select avg(maxHeight*1.0) as '각 지역별 최고키의 평균' from cte_usertbl;
④ ②,③의 쿼리를 합친다...
WITH cte_usertbl(addr,maxHeight)
as
(SELECT addr,max(height) from usertbl group by addr)
select avg(maxHeight*1.0) as '각 지역별 최고키의 평균' from cte_usertbl;