논리적인 작업의 단위를 묶어 DML에 의해 조작된 결과를 작업단위별로 제어하는 명령어인 Commit, Rollback, Savepoint등이 여기에 해당하며, 일부에서는 DCL(Data Control Language)로 분류하기도 한다.
① DDL
② DML
③ TCL
-> 트랜잭션을 제어하는 명령어
④ TML
① WHERE 절은 필수가 아니므로 생략 가능하다.
② DISTINCT 옵션을 통해 중복된 데이터가 있을 경우 1건으로 처리해 출력할 수 있다.
③ FROM 절이 없는 다음 문장 "SELECT COL1, COL2"은 에러 없이 수행된다.
-> SELECT, FROM은 필수이므로 생략되면 에러가 발생된다.
④ SELECT list에 서브쿼리가 사용될 수 있다.
① DML - SELECT
② TCL - GRANT
-> GRANT는 DCL
③ DCL - DROP
-> DROP은 DDL
④ DML - ALTER
-> ALTER은 DDL
[SQL]
SELECT SUM(COL2) + SUM(COL3) FROM TAB_A;
SELECT SUM(COL2) + SUM(COL3) FROM TAB_A WHERE COL1 > 0;
SELECT SUM(COL2) + SUM(COL3) FROM TAB_A WHERE COL1 IS NOT NULL;
SELECT SUM(COL2) + SUM(COL3) FROM TAB_A WHERE COL1 IS NULL;
[TAB_A]
COL1 | COL2 | COL3 |
---|---|---|
30 | NULL | 20 |
NULL | 50 | 10 |
0 | 10 | NULL |
1. SUM(집계함수)은 NULL을 무시한다. 60 + 30 = 90
2. COL1 > 0인 행은 첫번째 행 뿐이다(NULL값과의 비교연산은 FALSE를 리턴함)
NULL + 20 = NULL(NULL과의 연산 결과는 NULL을 리턴한다)
3. COL1 IS NOT NULL인 첫번째과 세번째 행의 SUM을 구한다. 10 + 20 = 30
4. COL1 IS NULL인 두번째 행의 SUM을 구한다. 50 + 10 = 60
③ 90, NULL, 30, 60
CREATE TABLE 서비스
(
서비스번호 VARCHAR2(10) PRIMARY KEY,
서비스명 VARCHAR2(100) NULL,
개시일자 DATE NOT NULL
);
[SQL]
㉠ SELECT * FROM 서비스 WHERE 서비스번호 = 1;
㉡ INSERT INTO 서비스 VALUES ('999', '', '2015-11-11');
㉢ SELECT * FROM 서비스 WHERE 서비스명 = '';
㉣ SELECT * FROM 서비스 WHERE 서비스명 IS NULL;
① 서비스번호 칼럼의 레코드 중 하나의 레코드라도 '001'과 같은 숫자 형식으로 입력되어 있다면 ㉠은 오류 없이 실행된다.
-> 서비스번호 칼럼의 모든 레코드가 001과 같은 숫자 형식으로 입력되어 있어야 오류가 발생하지 않는다.
② 오라클에서 ㉡과 같이 데이터를 입력하였을 때, 서비스명 칼럼에 공백 문자 데이터가 입력된다.
-> ㉡과 같이 데이터를 입력하면 서비스명 칼럼의 데이터에 대해서 오라클에서는 NULL로 입력된다.
③ 오라클에서 ㉡과 같이 데이터를 입력하고 ㉢과 같이 조회하였을 때, 데이터는 조회된다.
-> ㉡과 같이 데이터가 입력되어있을 때 오라클에서 데이터를 조회하려면 서비스명 IS NULL 조건으로 조회하여야한다.
④ SQL Server에서 ㉡과 같이 데이터를 입력하고 ㉣과 같이 조회하였을 때, 데이터는 조회되지 않는다.
-> ㉡과 같이 데이터가 입력되어있을 때 SQL Server에서 데이터를 조회하려면 서비스명 = '' 조건으로 조회하여야한다.
① LOWER('SQL Expert') : 'sql expert'
② UPPER('SQL Expert') : 'SQL EXPERT'
③ ASCII('A) : 65
④ LTRIM('xxYYZZxYZxx', 'x') : 'YYZZxYZ'
-> LTRIM은 첫 번째 인자 값인 문자열의 왼쪽 첫 문자부터 확인해서 두 번째 인자 값인 지정문자가 나타나면 해당 문자를 제거한다. 다른 문자 사이 또는 오른쪽에 있는 지정 문자는 제거되지 않는다. 따라서, LTRIM('xxYYZZxYZxx', 'x')의 결과는 'YYZZxYZxx' 이다.
-> 추가: SUBSTR/SUBSTRING(문자열, m[, n]): 문자열 중 m위치에서 n개의 문자 길이에 해당하는 문자를 돌려준다. n이 생략되면 마지막 문자까지이다.
[TAB1]
ROWNUM | C1 |
---|---|
1 | A |
↓ | |
A | |
2 | B |
↓ | |
B | |
↓ | |
B |
SELECT SUM(CC)
FROM
(
SELECT(LENGTH(C1) - LENGTH(REPLACE(C1, CHR(10))) + 1) CC FROM TAB1
);
③ 5
SELECT TO_CHAR(TO_DATE('2023.01.10 10', 'YYYY.MM.DD HH24') + 1/24/(60/10), 'YYYY.MM.DD HH24:MI:SS') FROM DUAL;
③ 2023.01.10 10:10:00
-> 오라클에서 날짜의 연산은 숫자의 연산과 같다. 1/24/60 = 1분을 의미한다. 1/24는 1시간을 의미한다. 1시간을 (60/10) 6으로 나누면 60분/6 = 10분이 된다. 2023년 1월 10일 10시에 10분을 더한 3번이 답이 된다.
고객 (고객번호, 고객이름, 주소, 전화번호)
상품 (상품번호, 상품이름, 무게, 가격)
주문 (고객번호, 상품번호, 수량, 날짜)
[SQL]
SELECT 고객이름, SUM(수량)
FROM 고객, 상품, 주문
WHERE 고객.고객번호 = 주문.고객번호
AND 상품.상품번호 = 주문.상품번호
GROUP BY 고객.고객이름
HAVING MAX(수량) > 10;
① 고객번호가 10보다 큰 고객이름과 주문한 수량의 합을 구한다.
② 수량이 10보다 큰 주문을 한 고객이름과 주문한 수량의 합을 구한다.
③ 열한 번 이상 상품을 주문한 고객이름과 주문한 수량의 합을 구한다.
④ 주문한 수량의 합이 10보다 큰 고객이름과 주문한 수량의 합을 구한다.
SELECT ENAME, EMPNO, MGR, ㉠ (MGR, 7698) AS NM FROM EMP;
① NULLIF
-> NULLIF(x,y) : x이 y와 같으면 NULL을, 같지 않으면 x를 리턴한다.
② NVL
-> NVL(x,y) / ISNULL(x,y) : x의 결괏값이 NULL이면 y의 값을 출력한다.
③ IFNULL
④ COALESCE
-> COALESCE(표현식1, 표현식2, ...) : 임의의 개수 표현식에서 NULL이 아닌 최초의 표현식을 나타낸다. 모든 표현식이 NULL이라면 NULL을 리턴한다.
① SELECT DNAME, LOC, DEPTNO
FROM DEPT
ORDER BY DNAME, LOC, 3 DESC;
-> 첫 번째 열, 두 번째 열은 오름차순 정렬, 3 DESC는 세 번째 열인 DEPTNO를 내림차순으로 정렬한다는 뜻.
② SELECT DNAME, LOC, DEPTNO
FROM DEPT
ORDER BY DNAME, AREA, DEPTNO DESC;
-> 첫 번째 열, 두 번째 열은 오름차순 정렬, 세 번째 열은 내림차순으로 정렬
③ SELECT DNAME, LOC AREA, DEPTNO
FROM DEPT
ORDER BY 1, AREA, 3DESC;
-> 첫 번째 열, 두 번째 열은 오름차순 정렬, 3 DESC는 세 번째 열인 DEPTNO를 내림차순으로 정렬한다는 뜻.
④ SELECT DNAME DEPT, LOC AREA, DEPTNO
FROM DEPT
ORDER BY DEPT DESC, LOC, 3 DESC;
-> 첫 번째 열과 세 번째 열을 내림차순으로 정렬하기 때문에 나머지와 결과가 다르다.
SELECT 학번
FROM 학생
WHERE 학생, 이름 LIKE ㉠
① '%S_ _ '
-> %위치에 아무런 문자가 들어가지 않을 수도 있다. 따라서 S가 첫 문자가 될 수도 있으므로 옳지 않다.
② '_S% __'
③ '_S % _ '
④ '_S _%'