응용 프로그램 개발자는 SELECT/INSERT/UPDATE/DELETE 를 잘 사용하는 것이 중요하다.
SELECT문 : 데이터베이스 내의 테이블에서 원하는 정보를 추출하는 명령. 가장 많이 사용하는 SQL 구문이다.
SELECT문의 기본 형식은 아래와 같다.
SELECT select_expr
[FROM table_references]
[GROUP BY {col_name | expr | position}]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}]
USE 구문
SELECT문을 사용하려면 먼저 사용할 데이터베이스를 지정해야 한다.
현재 사용하는 데이터베이스를 지정 또는 변경하는 구문 형식은 아래와 같다.
USE 데이터베이스_이름;
만약 employees 데이터베이스를 사용한다면 아래와 같이 입력한다.
USE employees;
"지금부터 employees라는 DB를 사용하겠으니, 모든 쿼리는 employees에서 수행하라"는 의미이다.
참고) SQL은 일반적으로 대소문자를 구분하지 않지만, 전체 대문자 또는 소문자 등으로 통일하는 것이 구문을 읽기 쉽게 한다. 이 포스팅에서는 예약어는 대문자로 작성한다.
SELECT와 FROM
SELECT * from titles;
위 SQL 구문에서, 일반적으로 *은 '모든 것'을 의미한다. (이곳에서 *은 모든 열을 의미함)
한마디로, 'titles 테이블에서 모든 열의 내용을 가져와라'는 의미이다.
SELECT first_name, last_name, gender FROM employees;
이렇게 한 열이나 여러 개의 원하는 열만 가져올 수 있다.
AS 별칭 지정
열 이름을 별도의 별칭(Alias)으로 지정할 수도 있다.
원래 열 이름 뒤에 AS 별칭 형식으로 사용하는데, 별칭 중간에 공백이 있다면 '(작은 따옴표)로 감싸줘야 한다.
또, AS 키워드는 붙여도 되고 생략해도 된다.
(권장사항으로는 별칭을 붙일 경우 되도록 '' 안에 별칭을 사용하자.)
SELECT first_name AS 이름, gender 성별, hire_date '회사 입사일' FROM employees;
WHERE 조건
WHERE : 조회하는 결과에 특정한 조건을 주어 원하는 데이터만 보고 싶을 때 사용하는 절이다.
아래와 같은 기본 형식을 갖는다.
SELECT 필드이름 FROM 테이블이름 WHERE 조건식;
아래와 같이 실제 사용할 수 있다.
SELECT * FROM usertbl WHERE name = '정상수';
WHERE 조건식에는 관계연산자(AND, OR, NOT 등)를 사용할 수 있다.
SELECT userID, Name FROM usertbl WHERE birthYear >= 1970 OR height >= 182;
이렇게 조건 연산자(=, <, >, <=, >=, != 등)와 관계 연산자(AND, OR, NOT 등)를 잘 조합하면 다양한 조건의 쿼리를 생성할 수 있다.
BETWEEN AND와 IN() 그리고 LIKE
아래 BETWEEN AND의 역할은 height >= 180 AND height <= 183 과 같다.
SELECT name, height FROM usertbl WHERE height BETWEEN 180 AND 183;
IN()을 사용하면 연속적인 값이 아닌 이산적인 값을 얻을 수 있다.
아래 IN()의 역할은 addr='경남' OR addr='전남' OR addr='경북' 과 같다.
SELECT name, addr FROM usertbl WHERE addr IN ('경남', '전남', '경북');
문자열의 내용을 검색하기 위해 LIKE 연산자를 사용할 수 있다.
%는 무엇이든 허용, _는 한 글자만 허용한다는 뜻이다.
SELECT name, height FROM usertbl WHERE name LIKE '김%';
(%나 _가 검색할 문자열의 제일 앞에 들어가면 MySQL 성능에 나쁜 영향을 끼칠 수가 있다.)
서브쿼리는 쿼리문 안에 또 쿼리문이 들어 있는 것을 뜻한다.
SELECT name, height FROM usertbl WHERE height > (SELECT height FROM usertbl WHERE name='정상수');
서브 쿼리(하위 쿼리)가 둘 이상의 값을 반환할 때는 ANY 혹은 ALL을 사용하여야 한다.
SELECT name, height FROM usertbl WHERE height >= ANY (SELECT height FROM usertbl WHERE addr='경남');
usertbl 테이블에 경남에 사는 사람의 키는 각각 170, 173이라고 했을 때 위 SQL문의 실행 결과로는 키가 173보다 크거나 같은 사람 또는 키가 170보다 크거나 같은 사람이 모두 출력될 것이다.
(결국 키가 170보다 크거나 같은 사람이 해당)
(SOME은 ANY와 동일한 의미로 사용됨)
SELECT name, height FROM usertbl WHERE height >= ALL (SELECT height FROM usertbl WHERE addr='경남');
ALL은 서브쿼리이 여러 개의 결과를 모두 만족시켜야 한다.
ORDER BY 정렬
ORDER BY절은 결과물에는 영향을 미치지 않지만, 결과가 출력되는 순서를 조절하는 구문이다.
SELECT name, mDate FROM usertbl ORDER BY mDate;
ORDER BY는 기본적으로 오름차순(ascending)으로 정렬된다.
내림차순으로 정렬하기 위해서는 열 이름 뒤에 DESC라고 적어주면 된다.
아래는 내림차순(descending)으로 정렬한 예이다.
SELECT name, mDate FROM usertbl ORDER BY mDate DESC;
아래와 같이 큰 순서대로 정렬하되, 키가 같으면 이름 순으로 정렬할 수 있다.
SELECT name, height FROM usertbl ORDER BY height DESC, name ASC;
SELECT userID FROM usertbl ORDER BY height 와 같이 ORDER BY에 나온 열이 SELECT 다음에 꼭 있을 필요는 없다.
ORDER BY 절은 SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY 중에 제일 뒤에 나와야 한다.
(ORDER BY절은 MySQL 성능을 상당히 떨어뜨릴 소지가 있기 때문에 꼭 필요한 경우가 아니면 되도록 사용하지 말자)
DISTINCT, 중복된 것은 하나만 남긴다
SELECT DISTINCT addr FROM usertbl;
LIMIT 출력 개수 제한
LIMIT N 구문으로 상위의 N개만 출력함으로써 MySQL의 부담을 많이 줄여줄 수 있다.
SELECT emp_no, hire_date FROM employees ORDER BY hire_date ASC LIMIT 5;
LIMIT 절은 'LIMIT 시작, 개수' 또는 'LIMIT 개수 OFFSET 시작' 형식으로도 사용할 수 있다.
시작은 0부터 시작하기 때문에, 5개를 출력하기 위해 아래처럼 사용해도 된다.
SELECT emp_no, hire_date FROM employees ORDER BY hire_date ASC LIMIT 0, 5; -- LIMIT 5 OFFSET 0과 동일
CREATE TABLE ... SELECT 테이블 복사
CREATE TABLE ... SELECT 구문은 테이블 복사에 주로 사용한다.
아래는 기본 형식이다.
CREATE TABLE 새로운테이블 (SELECT 복사할열 FROM 기존테이블)
CREATE TABLE buytbl2 (SELECT * FROM buytbl);
SELECT * FROM buytbl2;
필요하면 지정한 일부 열만 복사할 수 있다.
CREATE TABLE buytbl3 (SELECT userID, prodName FROM buytbl);
SELECT * FROM buytbl3;
복사할 때 PK나 FK 등의 제약 조건은 복사되지 않는다.