설모의 기록
[SQL 스터디] SQL 첫걸음 스터디 - 1 본문
하루 30분 36강으로 배우는 완전 초보의 SQL 따라잡기
Spring JPA 를 사용하기는 했지만 SQL 을 모르면 내부 쿼리가 어떻게 실행되는지를 잘 알지 못한채로 그냥 넘어가는 경우가 생길 수 있습니다. SQL 공부 해야지..해야지.. 하고 미루던 다짐을 스터디를 진행하며 실천하게 되었습니다.
우아한테크캠프에 참여할 당시, 교육을 해주시던 마스터님들이 추천해주신 책들을 바탕으로 계획을 짠 후에 스터디를 진행하기로 했습니다. (좋은 책 추천해주셔서 감사합니다. -HA, SH, YS의 깨알 인사)
이 책은 SQL 에 대해 깊은 내용까지 나와있지는 않지만 (그동안 알고 있었던 내용 복습 + 놓쳤던 부분) 에 대해 학습하기에 좋은 책입니다.
이번주에 책을 읽으며 스터디원들이 몰랐던 내용과 같이 만나 알게된 내용을 정리하겠습니다.
1차 스터디 정리
1. NULL
언어를 배울 때에 항상 마주치는 것이 NULL 인데요. 학교나 동아리에서 프로젝트를 할 때는 항상 데이터가 존재하는 테이블에 쿼리를 실행하는 것을 연습했었기 때문에 NULL 데이터에 대해 생각을 해본적이 사실 많지 않았습니다. 그래서 좀 흥미로웠던 내용입니다.
ORDER BY 로 컬럼을 지정해 정렬할 때, NULL 값을 가지는 행은 가장 먼저 표시되거나 가장 나중에 표시됩니다. - 데이터베이스 제품에 따라 기준이 다르지만 MySQL 의 경우 오름차순에서는 가장 먼저, 내림차순에서는 가장 나중으로 정렬됩니다.
NULL 값의 연산은 결과 또한 NULL 입니다. NULL 은 0 으로 처리되지 않습니다. - NULL + 1 → NULL - NULL * 2 → NULL - 1 / NULL → NULL
집계함수(예 : SUM(), AVG() 등) 에서는 NULL 은 무시됩니다. (예외 : COUNT() 는 * 를 넣을 시 NULL 값을 카운트하지만 다른 경우에서는 NULL 값을 카운트하지 않습니다.) - 예 : 각 레코드의 quantity 값이 1, 2, 10, NULL, 3 일 때 AVG(quantity) 의 값은 4 입니다.
NOT IN 을 이용할 때, 집합 안에 NULL 값이 있으면 왼쪽 값이 집합 안에 포함되어 있지 않아도 참을 반환하지 않습니다. - 예 : table1 에서 각 레코드의 no 값이 1, 2, 3, 4 일 때 아래의 쿼리가 반환하는 데이터는 없습니다. SELECT * FROM table1 WHERE no NOT IN (1, 2, NULL);
아래의 함수는 a 가 NULL 이면 b를, NULL 이 아니면 a 를 출력합니다. - MySQL : COALESCE(a, b) - Oracle : NVL(a, b)
2. 문자열 결합 연산
문자열데이터 결합하는 연산에 사용하는 연산자는 데이터베이스 제품마다 다릅니다. 따라서 사용하는 제품에 알맞는 연산자 또는 함수를 사용해야 합니다.
+ → SQL Server
|| → Oracle, DB2, PostgreSQL
CONCAT → MySQL
3. SQL 쿼리 내부 처리 순서
SQL 쿼리에서 내부 처리 순서는 다음과 같습니다.
WHERE → GROUP BY → HAVING → SELECT → ORDER BY - 위와 같은 순서로 SQL 쿼리가 처리가 되기 때문에 오른쪽 순서에서 정의한 별명을 왼쪽 순서에서 사용할 수 없습니다. - 옳은 예 : SELECT table1.name FROM table1; - 옳지 않은 예 : SELECT column1 as name FROM table1 WHERE name = '현아';
4. 복수열 갱신
UPDATE 명령의 SET 에서 콤마로 구분해 복수의 열을 갱신하려고 할 때, 실행 순서를 알아야 합니다. 먼저 기본이 되는 테이블과 실행할 쿼리는 아래와 같습니다.
실행할 쿼리 : UPDATE table1 SET no = no + 1, no2 = no;
위의 테이블 table1 에 쿼리를 실행하면 데이터베이스 제품 종류에 따라 다른 결과가 나타납니다.
(왼쪽 : MySQL, 오른쪽 : Oracle)
MySQL 에서는 no 값에 1을 더하여 no 에 저장한 후 그 값을 다시 no2 에 대입합니다. 그러나 Oracle 은 항상 갱신 전의 no 값을 반환하기 때문에 no2 에는 갱신되기 전의 no 값이 대입됩니다.
그러면 첫번째 기본 테이블에서 UPDATE table1 SET no2 = no, no = no + 1; 을 실행하면 결과는 어떻게 될까요?
결과는 MySQL, Oracle 모두 오른쪽 Oracle 의 결과였던 테이블 형태가 됩니다. 따라서 Oracle 은 갱신식 안에서 컬럼값을 참조할 때 항상 이전의 값을 반환하지만, MySQL 은 갱신 처리 순서를 고려할 필요가 있습니다.
5. 날짜 연산
SELECT CURRENT_DATE ± INTERVAL 일수 DAY; - 일수에 숫자를 넣으면 오늘 날짜에서 일수 만큼 연산을 한 DATE 값을 연산해줍니다.
날짜형 간의 뺄셈 - Oracle : '2018-08-25' - '1995-08-25' - MySQL : DATEDIFF('2018-08-25', '1995-08-25')
문자열 데이터를 날짜형 데이터로 변환 - Oracle : TO_DATE(char, format) → TO_DATE('20180825', 'YYYY-MM-DD') - MySQL : STR_TO_DATE(char, format) → STR_TO_DATE('2018-08-25', '%Y-%M-%D')
6. 결과의 행 제한
SELECT 컬럼명 FROM 테이블명 LIMIT 행수 [OFFSET 시작행]; - 결과를 찾은 후 '시작행'부터 '행수' 만큼 데이터를 제한해 반환합니다. - LIMIT 는 표준 SQL 이 아니라 MySQL 또는 PostgreSQL 에서 사용할 수 있습니다.
SELECT TOP 행수 컬럼명 FROM 테이블명; - 결과를 찾은 후 '행수' 만큼 제한해 반환합니다. - LIMIT 를 사용할 수 없는 SQL Server 에서 사용합니다.
SELECT 컬럼명 FROM 테이블명 WHERE ROWNUM <= 열번호; - 결과를 찾은 후 열번호가 '열번호' 보다 작거나 같은 데이터만 반환합니다. - Oracle 에서 사용합니다. - WHERE 절은 ORDER BY 보다 먼저 처리되기 때문에 정렬을 하려면 WHERE 절에서 사용하면 안되고 서브쿼리를 사용해야 합니다. (이유 : 정렬한 후에 열번호로 데이터를 제한해야 하기 때문입니다.)
'데이터베이스' 카테고리의 다른 글
[SQL 스터디] SQL 첫걸음 스터디 - 2 (0) | 2018.12.05 |
---|---|
mongoDB 사용법 (2) | 2017.10.09 |
MongoDB 설치법 (mac 기준) (0) | 2017.10.09 |
일주일 간격으로 데이터 개수 출력하기 (0) | 2017.06.22 |