ㅅㅇ
SQL : 04 DML & DQL 본문
_플레이데이터 빅데이터캠프 공부 내용 _5/24~25
MySQL : 04 DML & DQL
1. DML _ INSERT : 데이터 삽입
1.1. INSERT 기본 구문
INSERT INTO 테이블이름 (컬러명, 컬럼명 [,...]) VALUES (값1, 값2 [, ...]);
- INSERT는 한 행(Row, 레코드) 씩 처리한다.
- 문자열의 경우 삽입할 값을 '문자열값' 홀따옴표로 감싸준다. (sql은 큰따옴표 안됨.)
- 날짜는 형태에 맞게 문자열로 넣어준다. (날짜 '2022-03-22' 로 구분, 시간 03:22 로 구분)
- 테이블의 모든 컬럼에 데이터를 넣을 경우 컬럼 항목은 생략할 수 있다.
- 특정 컬럼에 값을 안 넣을 경우 INSERT할 컬럼 대상에서 제외하거나 null 키워드를 값에 넣는다.
- 행에 대한 식별자 첫 번째 컬럼으로 PK 제약조건 해주기
-- 1) member 테이블에 값(행-row, record) 추가: insert문
insert into member (id, passwd, name, point, join_date) values ('my-id', '1111', '홍길동', 30000, '2022-05-24' );
-- 만약에 이걸 위 명령을 또 실행했다고 하자. 그럼 오류남. 왜냐면 pk로 설정된 id에 똑같은 'my-id' 값 중복이기 때문에
-- 2) 전체 컬럼에 값을 모두 넣을 경우 컬럼 지정은 생략할 수 있다.
insert into member values ('my-id3', '3333', '유관순', 20000, '2020-12-24' );
-- 3)특정 컬럼에 값을 안 넣을 경우 insert 할 컴럼 대상에서 제외하거나 null 키워드를 값에 넣는다.
insert into member (id, passwd, name, join_date) values ('my-id4', '4324', '이순신', '2021-12-12');
insert into member (id, passwd, name, point, join_date) values ('my-id2', '1111', '홍길동', null, '2022-03-14' );
-- 테이블 데이터 확인
select * from member;
2. DQL _ SELECT : 데이터 조회
2.1. SELECT : 기본 구문
- 어떤 테이블(FROM), 어떤 컬럼(SELECT), [ 어떤 행(WHERE), 어떤 조건(HAVING), 어떤 그룹(GROUP), 어떤 순서(정렬. ORDER BY) ] 조회할 것인가?
SELECT 컬럼명1 [별칭], 컬럼명2 [별칭], ...
FROM 테이블이름 [별칭]
[WHERE 제약조건]
[GROUP 그룹화할 기준컬럼]
[HAVING 조건]
[ORDER BY 정렬기준컬럼 [ASC|DESC]]
- SECLECT 절 : 조회할 컬럼들 지정.
- 모든 컬럼 조회 시 *
- 별칭 지정 가능. 조호 결과의 컬러명을 별칭으로.
- 컬럼명 작성 시 create 만들 때와의 순서와는 상관없다. 지정한 순서대로 조회할 것.
- 같은 컬럼을 여러번 조회할 수 있다.
- FROM 절 : 조회대상 테이블 이름. 별칭 - 테이블 이름 대신 쿼리 내에서 사용할 별칭
- WHERE 절 : 조회할 행에 대한 선택 조건.
- GROUP 절 : 집계결과 조회 시 어떤 컬럼의 값이 같은 것끼리 묶어서 조회할 지 지정
- HAVING 절 : 집계결과 조회 시 그 결과에 대한 조회조건을 넣는다.
- ORDER BY : 조회 결과 정렬. ( ASC : 오름차순(Default), DESC : 내림차순 )
- SQL은 대소문자 구분을 안 한다. 값은 구분한다.
그러나, MySQL에서는 문자열 값 또한 구분하지 않는데 그러하더라도 값에 대해서는 대소문자 구분하여 작성하자.
(1) 테이블의 모든 컬럼의 모든 항목을 조회
select emp_id, emp_name, job, mgr_id, salary, comm_pct, dept_name from emp; -- 만약 순서 바꿔 조회할 거 아니면 이렇게 안 하고
select * from emp; -- *: 모든 컬럼
- 한 줄에 해도 되고 여러 줄에 해도 되고 들여쓰기해도 된다. SQL은 ; 만을 보고 명령의 끝을 판단때문.
가독성 있게 알아서. 구문별로 엔터쳐주고 라인 맞춰주는 게 좋음
(2) 테이블의 일부 컬럼 항목만을 조회
select emp_id, emp_name, job
from emp; -- 구문별로 엔터쳐주고 라인 맞춰주는 게 좋음
(3) 동일한 값은 하나씩만 조회되도록 조회 _ 속성 job 이 어떤 값들로 구성되었는 지 조회
- 컬럼이 categorical 형식 명목형일 때 뭘 분류할 때. 생별, 혈액형, bool -> 값이 n개로 결정되는.
=> distinct
select distinct job
from emp;
-- null도 값으로 표현되어 나온다.
-- 이때 job에 대한 중복값 아님. job과 dept_name 둘에 대한 중복값.
select distinct job, dept_name
from emp;
(4) 별칭으로 조회
- select 컬럼명 [as] 별칭 : 컬럼명으로 조회한 것을 별칭으로 보여줘라.
- as는 생략가능. (가독성을 위해 생략 유무 통일)
- 별칭에는 공백 넣을 수 없다. 주의. 공백 주면 구문이 떨어진 것으로 인식한다.
별칭에 컬럼명으로 못사용하는 문자(공백)를 쓸 경우 " "큰따옴표로 감싸준다.(이것도 가독성을 위해 통일)
** 이렇게 큰따옴표(별칭 내 공백 주고 싶을 때) 작은 따옴표(문자열 값을 표현) 역할이 다르기에 주의해서 써야 함.
select emp_id as 직원ID, -- emp_id 에서 조회한 결과를 직원ID 로 보여줘라.
emp_name as "직원 이름", -- 공백 표시를 위해 큰따옴표 ""에 넣음.
hire_date 입사일,
salary 급여,
dept_name 소속부서
from emp;
** 테이블 조회가 아니더라도, select 를 이용해 표로 확인 할 수 있다.
-- select 절에 상수값을 넣어서 확인. 테이블이 있는 게 아니니 from 생략.
select 10 as a, 20 as b;
select '안녕하세요' as 인사말;
select '2022-05-25' as "오늘 날짜";
2.2 SELECT : 연산자
- 컬럼이나 상수값에 사칙연산을 이용할 수 있다.
- SELECT 조회 컬럼에 사용 시 연산은 행 단위로 이뤄진다.
- 연산자 우선순위지정은 () 괄호로 묶는다.
[ 산술 연산자 ]
+, - , * , / , 나머지 : % mod , 몫 : div
-- 산술
select 20,
20+30 as 덧셈,
20-10 as 뺄셈,
20*3,
20/4,
10/3,
10%3,
10 div 3 as 몫,
10 mod 3 as 나머지;
-- 급여에 커미션_PCT를 곱한 값을 조회.
select salary * comm_pct '커미션'
from emp;
-- 급여(salary)을 연봉으로 조회. (곱하기 12)
select salary * 12 '연봉'
from emp;
- 피연산자가 null인 경우 무조건 결과는 null
null : 없는 값, 모르는 값
select 20 + null; -- null : 없는 값, 모르는 값
- 문자열 잇기. 문자열 등 모든 타입의 값을 합칠 때 사용.
: 여러개 값을 합쳐 문자열로 반환
= > concat(값, 값, ....)
- 문자열과 정수 또한 합칠 수 있다.
- concat 안에 들어가면 어떤 데이터 타입이든 쉼표를 기준으로 값으로 보고 합쳐 문자열로 반환한다.
-- 문자열과 모든 타입의 값을 합칠 때 사용
select concat('이름','홍길동'),
concat(20,40), -- 2040 이렇게 들어감.
concat('나이', 20); -- 나이20 -- 이렇게 정수와 문자열도 합칠 수 있다.
select emp_name,
concat('$ ',salary) as "salary"
from emp;
- 날짜 date/time/datetime +, - 연산
: 마지막 항목 (date:일, time: 초, datetime: 초) 의 값을 +/- 연산
=> 계산 결과가 정수형!으로 반환된다.
ex.) '2010-01-01' +1 => 20100102
- 근데, 여기서 날짜가 문자열 타입이면 연산을 할 수 없다. -> 문자열을 date타입으로 변환해야 함.
- cast() : 타입 변환 함수
select cast('2022-05-25' as date) -3; -- 문자열을 date타입으로 변환해야 함.
select cast('10:30:22' as time) -5;
- 연산은 그 컬럼의 모든 값들에 일률적으로 적용된다.
예를 들어 salary면 그 해당 컬럼의 값 모두 연산 ==> 원소 별로 연산!
-- EMP 테이블에서 직원의 이름(emp_name), 급여(salary) 그리고 급여 + 1000 한 값을 조회.
select emp_name,
salary,
salary + 10000
from emp;
-- 같은 행(원소 별로)끼리의 salary와 comm_pct 을 연산(*)
select salary,
comm_pct,
salary * comm_pct -- null연산은 결과 null
from emp;
** select 조회할 때
하드디스크에서 바로 클라이언트로 오는 게 아니다.
하드디스크에서 DBMS 메모리에 처리 결과(부른거)를 올리고
만약 별칭 설정, 제약 조건 등 명령했다면 DBMS에서 처리해주고 클라이언트에게 제공하는 것.
2.2. SELECT : WHERE 절을 이용한 행 선택
2.2.1. 구문 :
WHERE 컬럼 연산자 피연산자값;
-- EMP 테이블에서 직원_ID(emp_id)가 110인 직원의 이름(emp_name)과 부서명(dept_name)을 조회
select emp_name,
dept_name
from emp
where emp_id = 110; -- pk로 중복값없으니 있거나 없거나 임.
- 조회할 행에 대한 선택 조건 => 컬럼의 값들과 연산했을 때 True 인 행들만 조회 =>> Filter 개념
- where 절은 update, delete, select 에서 행을 선택할 때 사용한다.
- 조건이 여러 개인 경우 and 나 or로 연결한다.
- 연산의 우선순위를 바꿀 경우 () 괄호를 사용한다.
2.2.2. WHERE 절에서 사용하는 검색 조건의 주요 연산자
= : 같은 것 조회 != 또는 <> : 같지 않은 것 조회
-- EMP 테이블에서 'Sales' 부서에 속하지 않은 직원을 조회.
select * from emp
where dept_name != 'sales'; -- mysql에서는 대소문자 안가리고 조회되지만, db 오라클.. 가림. 값은 정확히 대소문자 맞춰주자.
-- where dept_name <> 'Sales';
-- EMP 테이블에서 급여(salary)가 $10,000를 초과인 직원을 조회
select * from emp
where salary > 10000;
-- 연봉(salary * 12) 이 200,000 이상인 직원들의 모든 정보를 조회.
select * from emp
where salary*12 >= 200000;
-- EMP 테이블에서 커미션비율(comm_p0.2~0.3 사이인 직원)
select *
from emp
where comm_pct between 0.2 and 0.3; -- 0.2 , 0.3도 포함. 이하 이상.
where comm_pct > 0.2 and comm_pact < 0.3
: a 와 b 사이에 있지 않은 데이터를 조회(a, b 값 포함하지 않음.)
select *
from emp
where comm_pct not between 0.2 and 0.3;
(4) IN(list)
: list 값 중 어느 하나와 일치하는 데이터를 조회. 같은 컴럼에 대해 or의 개념과 동일.
select emp_id, emp_name, job
from emp
where job in( 'IT_PROG', 'ST_MAN');
select emp_id, emp_name, job
from emp
where job not in( 'IT_PROG', 'ST_MAN');
'%' : 0글자 이상
LIKE '서울'% : 서울로 시작하는 0글자 이상
LIKE %'서울' : 서울로 끝나는 0글자 이상
LIKE &'서울'& : 중간에 서울이 들어가는 0 글자 이상
-- S로 시작하는
select emp_id, emp_name
from emp
where emp_name like 'S%';
-- en으로 끝나는
select emp_id, emp_name
from emp
where emp_name like '%en';
'_' : 한글자
LIKE _서울 LIKE 서울_ LIKE _서울_ : 한글자만 차지.!
-- EMP 테이블에서 직원 이름(emp_name)의 세 번째 문자가 “e”인 모든 사원의 이름을 조회
select emp_id, emp_name
from emp
where emp_name like '__e%';
- 만약 이름에 '%' 가 들어가는 직원 조회한다면? '%%%'??
-- >> 패턴문자를 조회조건에서 Literal로 사용해야 하는 경우 --> escape 구문을 이용해 패턴문자를 검색문자로 표시하는 특수문자를 지정한다.
where emp_name like '%#%%' escape '#';
#뒤에 패턴문자가 오면 literal라고 정해주는 것. 어떤 거 뒤에 올지는 본인이 지정.
(7) NOT LIKE
: 문자 형태와 알치하지 않는 데이터를 조회
select emp_id, emp_name
from emp
where emp_name not like 'S%';
(8) IS NULL
select emp_id, emp_name, dept_name
from emp
where dept_name is null;
select emp_id, emp_name, dept_name
from emp
where dept_name is not null;
not (where 조건)
not (dept_name is null)
not dept_name in ('Shipping')
-- 이렇게 not 연산자를 써서도 구현 가능하다.
괄호는 상관없지만 해주는 게 좋음.
EX. 날짜 비교 연산 예제
- date/datetime에서 년도만 추출: year(값).
ex) year('2020-10-10') => 2020
- cast 타입변환 함수 사용도 가능. year 데이터타입으로 변환
-- hire_date는 date type
-- year() 함수로 년도만 추출.
-- 2007년 이후 입사한 직원 조회.
select emp_id, emp_name, year(hire_date)
from emp
where year(hire_date) >= 2007;
-- 2004년에 입사한 직원조회
-- cast 타입변환 함수 사용
select emp_id, emp_name, hire_date
from emp
-- where year(hire_date)=2004;
where cast(hire_date as year) =2004;
--2005년 ~ 2007년 사이에 입사(hire_date)한 직원 조회.
select emp_id, emp_name, job, hire_date
from emp
where year(hire_date) between 2005 and 2007;
2.2.3. WHERE 조건이 여러 개인 경우
- AND OR : 논리 연산자로 조건이 하나 이상일 경우 연결 연산자.
(조건) AND (조건) -> 참 and 참 -> 참 : 조회 결과 행. 하나라도 거짓이면 조회 결과 행 아님.
(조건) OR (조건) -> 거짓 or 거짓 -> 거짓 : 조회 결과 행이 아님. 하나라도 참이면 조회 결과 행.
NOT (조건) : 조건의 반대
- 조건 세 개 이상이면 --> 연산 우선순위 : and > or
where 조건1 and 조건2 or 조건3
1. 조건 1 and 조건2
2. 1번의 결과 or 조건3
- or를 먼저 하려면 괄호 쳐줘야 한다. --> where 조건1 and (조건2 or 조건3)
ex) 괄호 유무로 bool 이 달라지기에 주의해야 한다.
where 참 or 거짓 and 거짓 ; => 참 or (거짓) => 참
where (참 or 거짓) and 거짓 ; => (참) and 거짓 => 거짓
-- 부서이름(dept_name)이'Executive'나 'Shipping' 이면서 급여(salary)가 6000 이상인 사원의 모든 정보 조회.
-- 한 컴럼에 관한 것은 in 연산자로 가능.
select * from emp
where dept_name in ('Executive', 'Shipping') and salary >= 6000;
-- 업무(job)에 'MAN'이 들어가는 직원들 중 급여(salary)가 $10,000 이하이 거나 2008년 이후 입사한 직원 조회
select * from emp
where job like '%MAN%' and (salary <= 10000 or year(hire_date) >=2008);
**
-- 가끔 이렇게 쓸 때가 있긴 하다.
select * from emp
where 1 != 1; -- 아무 데이터도 조회하지 않음.
select * from emp
where 1 = 1; -- 모든 데이터 조회
2.4. SELECT : ORDER BY 를 이용한 정렬
- 컬럼 행의 한 속성 데이터만 정렬되는 것이 아니다. 한 행 단위로, 한 행 자체가 정렬된다.
- 워크벤치 클라이언트에서 정렬 기능이 있긴 함.
- order by절은 select문의 마지막에 온다. 순서 지켜야 한다.
- 정렬 설정 안 했을 경우, mysql은 가장 빨리 찾을 수 있는 순서대로 출력된다. 그게 바로 pk 오름차순 정렬.
2.4.1. 구문
select 컬럼선택
from 테이블 선택
where 행선택
order by 정렬기준컬럼 정렬방식 [, ...];
(1) 정렬기준컬럼 지정 단위: 컬럼이름, 컬럼의순번(select절의 선언 순서) 둘 중 아무거나.
ex )
select salary, hire_date
from emp ... 에서 salary 컬럼 기준 정렬을 설정할 경우.
order by salary 또는 1
(2) 정렬방식
- ASC : 오름차순, 기본방식(생략가능)
- DESC : 내림차순
- 문자열 오름차순 : 특수문자 -> 숫자 -> 대문자 -> 소문자 -> 한글 (unicode 순서)
- Date 오름차순 : 과거 -> 미래
- null 오름차순 : 맨처음에 나온다.
-- 컬럼명을 기준으로 정렬해라.
select emp_id, emp_name, salary
from emp
where salary >5000
order by salary desc;
-- select 절의 3번째 컬럼을 기준으로 정렬해라.
select emp_id, emp_name, salary
from emp
where salary >5000
order by 3 desc;
- N차 정렬 가능
예를 들어,
업무(job) 순서대로 (A -> Z) 조회하고 업무(job)가 같은 직원들은 급여(salary)가 높은 순서대로
2차 정렬해서 조회가 가능.
--> 정렬할 때 그 값이 같은 애들 사이에서 또 정렬하고 싶다. 2차 정렬, 3차 정렬 ....
-- 1차로 job 오름차순 정렬
-- 2차로 salary 내림차순 (job이 같은 것 안에서 정렬)
-- 3차 name 내림차순 (salary 같은 것 안에서 정렬)
select emp_id, emp_name, job, salary
from emp
order by job asc, salary desc, emp_name desc;
'SW_STUDY > SQL' 카테고리의 다른 글
SQL : 06 조인 (0) | 2022.05.29 |
---|---|
SQL : 05 함수 (2) 집계함수 (0) | 2022.05.26 |
SQL : 05 함수 (1) (0) | 2022.05.26 |
SQL : 02 기본 SQL문 & 03 DDL (0) | 2022.05.24 |
SQL : 01 Database 개요 (0) | 2022.05.24 |