ㅅㅇ

SQL : 04 DML & DQL 본문

SW_STUDY/SQL

SQL : 04 DML & DQL

SO__OS 2022. 5. 24. 22:33

_플레이데이터 빅데이터캠프 공부 내용 _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 절에서 사용하는 검색 조건의 주요 연산자 

 
(1) 비교 연산자 이용

= : 같은 것 조회       !=  또는 <> : 같지 않은 것 조회

> ,  <  ,  >=,  <=
-- 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;

 

(2)  BETWEEN a AND b
: a 와 b 사이의 데이터를 조회 (a, b 값 포함)
-- 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  
 
(3) NOT BETWEEN a AND b

: 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');
 
(5) NOT IN(list)
: list의 값과 일치하지 않는 데이터를 조회
select emp_id, emp_name, job
from   emp
where  job not in( 'IT_PROG',  'ST_MAN');
 
(6) LIKE
: 문자 형태로 부분일치하는 데이터를 조회

 '%' : 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

- where dept_name = null 라는 구문은 틀렸다.
   null은 없는 값. 없는 값은 비교할 수 있는 대상이 아니다.
   그래서 아예 연산자  IS NULL 를 만듦. 근데 이렇게 해도 정상실행되는데 이를 주의하기.
select emp_id, emp_name, dept_name
from   emp
where  dept_name is null;
 
(9) IS NOT NULL
-  이거 외에는 연산자 앞에 not을 붙였는데, 여기서는 is not null
select emp_id, emp_name, dept_name
from   emp
where dept_name is not null;
 
** NOT 연산자 이용 가능.
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