본문 바로가기
국비학원

[국비지원] KH 정보교육원 36일차 (1/2)

by 도전하는 개발자 2022. 5. 17.

kh day 036

오늘은 SQL문의 WHERE절 ORDER BY절을 배우며 SELECT문을 마무리했다. SQL문을 빨리 배우고 싶었는데 진도가 느려서 조급한 마음이 있었는데 수업이 이제 속도감 있게 진행되니 좋은 것 같다! 오랜만에 제대로 공부하는 기분이 난다 ㅎㅎ 요즘 자바 언어 복습에 신경을 쏟고 있는데 SQL도 누적 학습량이 늘어나는 만큼 이제 신경을 써야겠다. 자바 시간에는 람다식의 기초를 배웠다. 제네릭도 처음에는 뭔가 어려울 것 같고 부담스러웠는데 별거 없었듯이 람다식도 아직까지는 딱히 큰 어려움 없이 수업을 따라갈 수 있는 것 같다. 앞으로도 뒤쳐지지 않고 열심히 따라가야지!!!

 

---

 

이번 주 공지사항!!

1. 화요일 SQL활용 능력단위 평가시험!

2. SQL문
   지난주 : DQL 문장 절반
   이번주 : DQL 완성, DML, TCL까지 끝내고 DDL 도입 
   DQL 다 배우고 바로 조별과제 시작 (과제당 3문제씩 2~3번에 걸쳐 진행)

3. 자바언어
   지난주 : 제네릭 완성 
   이번주 : 람다식 잘 이해해야함! 
              익명구현객체 코딩기법이 익숙하지 않으면 람다식 이해에 어려움이 있다
              같이 복습할 것이지만, 개인적으로 추가학습 필요 
              람다식 완성 -> JCF (대용량 데이터를 위한 자료구조) 들어감

---

SQL문

------------------------------------------------------
* Comparison Operators (비교연산자)
------------------------------------------------------
(1) operand1  =   operand2 ( == 아님 주의)
(2) operand1  !=  operand2 
    operand1  <>  operand2 (잘 안 씀) 
    operand1  ^=  operand2
(3) operand1  >   operand2
(4) operand1  <   operand2
(5) operand1  >=  operand2
(6) operand1  <=  operand2


SELECT
    employee_id,
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
    salary >= 10000; -- 체크조건 (행 필터링)

-> 체크조건으로 필터링해서 salary가 10000 이상인 애들만 보여줌

SELECT
    employee_id,
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
   last_name = 'King'; -- SQL문에서는 문자열 ''으로 표시
                                ""는 AS 만들 때 사용

-> 성이 King인 애들만 뽑아서 보여줌
    대소문자 구분함!

SELECT
    employee_id,
    last_name,
    salary,
    hire_date  -- 채용일자 (DATE 타입)
FROM
    employees;

-> 개발도구마다 hire_date가 출력되는 방식이 다름!

 

hire_date - VS
hire_date - SQL*Developer



 Date output format: RR(년)/MM(월)/DD(일) only in the oracle SQL*Developer

<NUMBER> <-> <CHARACTER> <-> <DATE> 간에는,
자동형변환이 됨!!! (*****)

따라서, 아래의 조건식은 <DATE> > <CHARACTER> 의 비교식으로
자동형변환에 의해, 당연히 비교가 가능해짐!

SELECT
    employee_id,
    last_name,
    salary,
    hire_date 
FROM
    employees
WHERE 
   hire_date > '07/12/31'; -- 07/12/31 이후 입사자만 필터링해서 보여줌

 



*자바언어는 자동형변환으로 하는걸 권장하지만 SQL은 아님!!!!
자동형변환을 포기하고, 강제형변환 함수인 to_date()로 직접
DATE 타입으로 형변환시켜서, 비교하자 why? 가독성 확보

SELECT
    employee_id,
    last_name,
    salary,
    hire_date 
FROM
    employees
WHERE
    hire_date > to_date('07/12/31', 'RR/MM/DD'); -- 이렇게 쓰자 (이러면 VS에서도 가능)

------------------------------------------------------
* BETWEEN operator: 
WHERE column BETWEEN start AND end ( start <= X <= end )
------------------------------------------------------

SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
WHERE
    salary BETWEEN 7000 AND 8000; 

--> salary가 7000이상 8000이하인 애들만 보여줌


SELECT 
    employee_id, 
    last_name, 
    salary, 
    hire_date
FROM 
    employees
-- WHERE 
--     hire_date BETWEEN '07/01/01' AND '08/12/31';          
--     이렇게 쓰지말고 강제형번환 해주자
    
WHERE 
    hire_date 
        BETWEEN to_date('07/12/31', 'RR/MM/DD') 
        AND to_date('08/12/31', 'RR/MM/DD'); -- 이렇게 쓰자 (이러면 VS에서도 가능)

-> 08년도에 입사한 사람들 보여줌


------------------------------------------------------
* IN Operators (집합연산자)
WHERE column IN ( value1, value2, ... )
------------------------------------------------------

SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
WHERE
    employee_id = 100
    OR employee_id = 200
    OR employee_id = 300; -- 아이고 코드 길다

SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
WHERE
    employee_id IN ( 100, 200, 300); -- 이렇게 쓰자! -- 집합원소유형 : 숫자도 가능

 


SELECT
    employee_id,
    first_name,
    last_name,
    job_id,
    salary,
    hire_date
FROM
    employees
WHERE
    last_name IN ('King', 'Abel', 'Jones');         -- 집합원소유형: 문자열도 가능!


SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees

-- WHERE
--    hire_date IN ('01/01/13', '07/02/07');        -- 집합원소유형: 날짜도 가능!
-- 이렇게 쓰지말고 강제형변환 해주자

WHERE
    hire_date IN (
        to_date('01/01/13', 'RR/MM/DD'), 
        to_date('07/02/07', 'RR/MM/DD')
    ); -- 이렇게 써주자!

 




------------------------------------------------------
* LIKE Operators (패턴매칭연산자)
WHERE column LIKE <패턴> -- LIKE는 ~와 같다는 의미
------------------------------------------------------
<패턴>에 사용가능한 Wildcard 문자들:
 (1) %  (모든 문자)      ( x >= 0,     x: 문자개수 )
 (2) _   (한 글자)         ( x == 1,     x: 문자개수 )
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE 'J%';        -- % : x >= 0 (x: 문자개수)

-> 성이 J로 시작하는 직원 필터링해서 보여줌

SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '%ai%';      -- % : x >= 0 (x: 문자개수)

-> 성에 ai가 들어가는 직원 필터링해서 보여줌

SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '%in';       -- % : x >= 0 (x: 문자개수)

-> 성이 in으로 끝나는 직원 필터링해서 보여줌

--

SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '_b%';       -- % : x >= 0, _ : x == 1 (x: 문자개수)

-> 성의 두번째 글자가 b고, (뒤에는 오던말든 관심없는) 직원 필터링해서 보여줌

--

SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '_____d';    -- _ : x == 1 (x: 문자개수)

-> 성의 앞에 5개의 문자가 오고, d로 끝나는 직원 필터링해서 보여줌


SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '%d';        -- % : x >= 0 (x: 문자개수)

-> 성이 d로 끝나는 직원 필터링해서 보여줌



---

SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '%'; -- 성이 0 문자 이상인 직원
    -- last_name LIKE '%_%'; -- 성이 한 문자 이상인 직원
    -- last_name LIKE '_'; -- 성이 한 문자인 직원
    -- last_name LIKE '%%'; -- 성이 0문자 이상인 직원
    -- last_name LIKE '%' || 'a' || '%'; -- 성에 a가 포함된 직원


*탈출문자(Escape Character):
특수한 의미를 가지는 기호의 기능을 없애는 문자를 "탈출문자"라고 함.

SELECT
    employee_id,
    last_name,
    salary,
    job_id
FROM
    employees
WHERE
    job_id LIKE '%$_%' ESCAPE '$'; 
    -- 이제 $바로 뒤의 _는 일반 문자로 간주함
    -- job_id 행 안에 _가 들어간 애들을 필터링해서 보여줌

 

 


SELECT
    employee_id,
    last_name,
    salary,
    job_id
FROM
    employees
WHERE
    job_id LIKE '%E___' ESCAPE 'E'; 
   -- 이 경우 E바로 뒤의 _는 일반문자로 간주함    
   -- job_id 행 안에 _가 들어가고, 뒤에 두개의 문자가 오는 애들을 필터링해서 보여줌

---

------------------------------------------------------
* Logical Operators (논리연산자)
 (1) AND (그리고) : 두 조건을 모두 만족하는 경우 TRUE!
 (2) OR  (또는)  : 두 조건중, 한가지만 만족해도 TRUE!
 (3) NOT (부정)  : 지정된 조건이 아닌 데이터를 검색
-- ------------------------------------------------------

(1) (2)

SELECT
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
    job_id = 'IT_PROG'
    AND salary >= 5000;
    -- OR salary >= 5000;


---

(3) 

1. NOT 연산자

SELECT
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
   NOT salary < 20000;         -- 필터링해서 급여가 20000 초과인 직원 보여줌
   -- ( NOT salary < 20000 );  -- 상동
   -- NOT ( salary < 20000 );  -- 상동


2. NOT IN 연산자

SELECT
    last_name, 
    job_id,
    salary
FROM
    employees
WHERE
   salary NOT IN ( 9000, 8000, 6000 );         -- 필터링해서 급여가 9000, 8000, 6000이 아닌 직원들 보여줌
   -- NOT ( salary IN ( 9000, 8000, 6000 ) );  -- 상동


3. NOT LIKE 연산자

SELECT
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
    last_name NOT LIKE 'J%';       -- 필터링해서  성이 J로 시작하지 않는 직원들 보여줌
    -- NOT last_name LIKE 'J%';    -- 상동
    -- NOT (last_name LIKE 'J%');  -- 상동


4. NOT BETWEEN a AND b 연산자
    NOT (a <= x <= b)  -->  (x < a, x > b)

SELECT
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
    salary NOT BETWEEN 2400 AND 20000;      -- 필터링해서 월급여가 20000 넘고 2400 안 되는 직원들 보여줌
    -- NOT (salary BETWEEN 2400 AND 20000); -- 상동


5. IS NULL 연산자 (*******)

SELECT
    last_name,
    job_id,
    salary,
    commission_pct
FROM
    employees
WHERE
--  commission_pct = NULL;    -- NULL은 =로 비교하면 안 됨 (값이 없는데 비교연산자 어케쓰겟음)
    commission_pct IS NULL;    -- IS NULL로 물어봐야함. 필터링해서 커미션이 없는 직원 보여줌

-- WHERE
--    nvl(commission_pct, -1) = -1;    -- 필터링해서 커미션이 없는 직원 보여줌
      -- 커미션이 없는 (NULL값인) 직원의 커미션을 -1로 바꾸고, 커미션이 -1인 직원 보여줌


 6. IS NOT NULL 연산자
SELECT
    last_name,
    job_id,
    salary,
    manager_id
FROM
    employees
WHERE
    manager_id IS NOT NULL;    -- 필터링해서 manager_id가 null이 아닌 직원들만 보여줌



------------------------------------------------------
연산자 우선순위 (The operator's priorities)

(1) 괄호( )
(2) 비교 연산자
(3) NOT 연산자
(4) AND 연산자  - 혼동주의
(5) OR 연산자    - 혼동주의

 * 우선순위: 괄호( ) > 비교 > NOT > AND > OR
------------------------------------------------------

-- 1. AND 연산자가 우선실행 : 예상치 못한 결과

SELECT
    last_name,
    job_id,
    salary,
    commission_pct
FROM
    employees
WHERE
    job_id ='AC_MGR' OR job_id='MK_REP'   -- 얘가 마지막
    AND commission_pct IS NULL               -- 얘가 첫번째
    AND salary >= 4000                            -- 얘가 두번째
    AND salary <= 9000;                            -- 얘가 세번째

-> AC_MGR은 AND 연산자 3개를 만족하는 애가 없어서 이상한 결과가 나옴




-- 2. 연산자 우선순위 조정(소괄호 이용): 올바른 결과
SELECT
    last_name,
    job_id,
    salary,
    commission_pct
FROM
    employees
WHERE 
    ( job_id ='AC_MGR' OR job_id='MK_REP' ) -- 괄호를 쳐서 먼저 연산하게끔 하자
    AND commission_pct IS NULL
    AND ( salary BETWEEN 4000 AND 9000 )   -- 이렇게 써주자


------------------------------------------------------
 ORDER BY clause (사실 안 쓰는게 좋다)

SELECT [DISTINCT] {*, column [Alias], . . .}
 FROM 테이블명
 [ WHERE 조건식 ]
 [ ORDER BY { column|표현식} [ASC|DESC] ];
------------------------------------------------------


1. 숫자 데이터 정렬

SELECT
    employee_id,
    last_name,
    job_id,
    salary
FROM
    employees
ORDER BY
   salary;           -- default: ASC (오름차순 정렬)
   -- salary ASC;       -- 오름차순 정렬 (ascending)
   -- salary DESC;     -- 내림차순 정렬 (descending)  


SELECT
    employee_id,
    last_name,
    job_id,
    salary + 100 AS "월급"
FROM
    employees
ORDER BY
    월급 DESC;            -- 컬럼별칭으로 내림차순 정렬
    -- salary +100 DESC;   -- 표현식으로 내림차순 정렬
    -- 4 DESC;                 -- 컬럼인덱스로 내림차순 정렬 (이런거 쓰지마세요)



2. 문자 데이터 정렬

SELECT
    employee_id,
    last_name AS 이름,
    job_id,
    salary
FROM
    employees
ORDER BY
    last_name ASC;  -- 컬럼명으로 오름차순 정렬
    이름 ASC;         -- 컬럼별칭으로 오름차순 정렬
    2 ASC;             -- 컬럼인덱스로 오름차순 정렬 (이런거 쓰지마세요)


3. 날짜 데이터 정렬

SELECT
    employee_id,
    last_name,
    salary,
    hire_date AS 입사일
FROM
    employees
ORDER BY
    hire_date DESC;     -- 컬럼명으로 내림차순 정렬
    -- 입사일 DESC;     -- 컬럼별칭으로 내림차순 정렬
    -- 4 DESC;            -- 컬럼인덱스로 내림차순 정렬 (이런거 쓰지 마세요)


4. 다중컬럼 정렬
------------------------------------------------------
SELECT [DISTINCT] {*, column [Alias], . . .}
FROM 테이블명
[WHERE 조건식]
ORDER BY 
 {column1 or 표현식1} [ASC or DESC], 
 {column2 or 표현식2} [ASC or DESC];
------------------------------------------------------

SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
ORDER BY 
    salary DESC,       -- 컬럼명1로 내림차순 정렬
    hire_date;          -- 컬럼명2로 오름차순 정렬

 

 


--> 이 경우 먼저 쓴 salary를 내림차순을 정렬하고,
     salary 칼럼 중에 같은 값을 가진 녀석들을
     hire_date로 오름차순 정리함


5. NULL값 정렬

Oracle 에서 가장 큰 값은, NULL 값임!!!
(값이 없기 때문에, 값의 크기를 비교불가)
따라서, 내림차순 정렬시, 가장 큰 값이 NULL 이 우선

SELECT
    employee_id,
    last_name,
    commission_pct
FROM
    employees
ORDER BY
   commission_pct DESC;     -- 컬럼명으로 내림차순 정렬 (NULL이 가장 먼저 나옴)
   -- commission_pct ASC;   -- 컬럼명으로 오름차순 정렬