36일차 DQL마지막 부분과 람다식

쿠우·2022년 5월 16일
0

WHERE절에 들어가는 서술어

1. 비교연산자와 BETWEEN a AND b

-- ------------------------------------------------------
-- 1. Comparison Operators (비교연산자)
-- ------------------------------------------------------
-- 1. operand1  =   operand2
-- 2. operand1  !=  operand2, 
--    operand1  <>  operand2, -> 해외에서 많이 씀 !=와 같음
--    operand1  ^=  operand2  -> XOR
-- 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;


SELECT
    employee_id,
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
   last_name = 'King';
-- WHERE
--     last_name = 'KING';


-- Date output format: RR/MM/DD only in the oracle SQL*Developer

SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees

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

-- 따라서, 아래의 조건식은 <DATE> > <CHARACTER> 의 비교식으로
-- 자동형변환에 의해, 당연히 비교가 가능해짐!
WHERE 
   hire_date > '07-12-31';     --  프로모션 이용해서 이렇게 쓰면안된다 명시적으로 해주는 것이 좋음

-- 자동형변환을 포기하고, 강제형변환 함수인 to_date()로 직접 
-- DATE 타입으로 형변환시켜서, 비교하는 이유는: 가독성 확보 
-- WHERE
--     hire_date > to_date('07/12/31', 'RR/MM/DD'); --이렇게 해주는 것이 좋다. 자바언어와 반대다. 


-- ------------------------------------------------------
-- 2. 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;


SELECT 
    employee_id, 
    last_name, 
    salary, 
    hire_date
FROM 
    employees
--      OK only on the Oracle SQL*Developer       
-- WHERE 
--     hire_date BETWEEN '07/01/01' AND '08/12/31';           --포맷이 달라 안된다. vs코드 작동안됌.
    
WHERE 
    hire_date 
        BETWEEN to_date('07/12/31', 'RR/MM/DD')        -- 포맷을 맞춰준다. 작동됌 프로모션에 의존하지말라
        AND to_date('08/12/31', 'RR/MM/DD');

2. 집합연산자

(중복 비허용, 순서를 보장하지 않는다!)



-- ******************************************************
-- SELECT 문의 기본구조와 각 절의 실행순서
-- ******************************************************
--  - Clauses -                 - 실행순서 -
--
-- SELECT clause                    (5) : 항상 마지막에서 두번째로 두행 
-- FROM clause                      (1)
-- WHERE clause                     (2) : 1차 필터링 수행 (행 필터링)
-- GROUP BY clause                  (3) : 그룹핑
-- HAVING clause                    (4) :2차 필터링 수행 (그룹 필터링)
-- ORDER BY clause                  (6) : 항상 마지막에 수행
-- ******************************************************


-- ------------------------------------------------------
--        *** SELECT 문의 기본문법 구조 ***
-- ------------------------------------------------------
-- SELECT [DISTINCT] { *, column [AS] [alias], ... }
-- FROM <테이블명>
-- WHERE <predicates>
-- ------------------------------------------------------

-- ------------------------------------------------------
-- 1. IN Operators (집합연산자)
-- ------------------------------------------------------
-- WHERE column IN ( value1, value2, ... )
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
WHERE
    employee_id IN ( 100, 200, 300);

-- 수학의 집합의 성질을 기억해야 합니다!!!
-- (중복 비허용, 순서를 보장하지 않는다!) 
-- WHERE
--    employee_id IN ( 100, 100, 200, 200, 300);    -- 집합원소유형: 1. 숫자


SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
WHERE
    -- 참고: 논리연산자 (AND, OR, NOT) = (그리고, 또는, 부정)
    employee_id = 100
    OR employee_id = 200
    OR employee_id = 300;


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


SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
-- WHERE
--    hire_date IN ('01/01/13', '07/02/07');        -- 집합원소유형: 3. 날짜, OK only on the Oracle SQL*Developer
WHERE
    hire_date IN (
        to_date('01/01/13', 'RR/MM/DD'), 
        to_date('07/02/07', 'RR/MM/DD')
    );

3. 패턴매칭연산자

-------------------------------------------------

-- ------------------------------------------------------
-- 1. LIKE Operators (패턴매칭연산자)
-- ------------------------------------------------------
-- WHERE column 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: 문자개수)


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


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


-- ------------------------------------------------------

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

-- ------------------------------------------------------


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


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

-- ------------------------------------------------------


SELECT
    employee_id,
    last_name,
    salary
FROM
    employees
WHERE
    last_name LIKE '%';

    --  '%_%' - 적어도 한문자는 있어야한다는 패턴   -- % : x >= 0, _ : x == 1 (x: 문자개수)
    -- '_' 정확하게 1개만 있는 단문자여야만한다.  
    -- '%%' %와 같다.
    --'%'; 모든 패턴
    -- '%' || 'a' || '%'  -- 연결연산자로 연결 a가 포함된 문자를 전부 조회

SELECT
    employee_id,
    last_name,
    salary,
    job_id
FROM
    employees
WHERE
    -- 탈출문자(Escape Character): 와일드 카드로부터 특수한 의미를 없애버린다.
    -- 특수한 의미를 가지는 기호의 기능을 없애는 문자
    -- 를 "탈출문자"라고 함.
    -- $부터는 문자로서의 기능을함
    job_id LIKE '%$_%' ESCAPE '$';      -- % : x >= 0, _ : x == 1 (x: 문자개수)
    --          '%_%'와 같다. ('_':일반문자)

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

    --탈출 문자를 만나서 바로 뒤에 패턴문자 '_' 는 일반문자로 읽힘 뒤에 2개의 '_'는 다시 패턴문자 

4. 논리연산자 (1,2 = 자바랑 비슷한 맥락)

-- ------------------------------------------------------
-- 1. Logical Operators (논리연산자)
-- ------------------------------------------------------
--  (1) AND (그리고) : 두 조건을 모두 만족하는 경우 TRUE!
--  (2) OR  (또는)  : 두 조건중, 한가지만 만족해도 TRUE!
--  (3) NOT (부정)  : 지정된 조건이 아닌 데이터를 검색
-- ------------------------------------------------------
SELECT
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
    job_id = 'IT_PROG'
    AND salary >= 5000;

-- ------------------------------------------------------

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

5. 논리연산자

(부정 = ~이 아닌 값)
(NULL값은 IS NULL)


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

-- 1. NOT 연산자
SELECT
    last_name,
    job_id,
    salary
FROM
    employees
-- WHERE
--    NOT salary < 20000;
WHERE
   ( NOT salary < 20000 ); -- 비교연산우선되고 부정연산이 수행
-- WHERE
--     NOT ( salary < 20000 );


-- 2. NOT IN 연산자
SELECT
    last_name, 
    job_id,
    salary
FROM
    employees
-- WHERE
--    salary NOT IN ( 9000, 8000, 6000 ); -- 실무에서 평범한 형태 
WHERE
    NOT ( salary IN ( 9000, 8000, 6000 ) ); --위에 것과 같다. 


-- 3. NOT LIKE 연산자
SELECT
    last_name,
    job_id,
    salary
FROM
    employees
WHERE
    last_name NOT LIKE 'J%'; --대문자 J로 시작하는 직원빼고 다 출력
-- WHERE
--    NOT last_name LIKE 'J%'; --위에랑 똑같다.
-- WHERE
--    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; --해당 범위 뺴고 나머지
-- WHERE
--    NOT (salary BETWEEN 2400 AND 20000); 


-- 5. IS NULL 연산자 (*******) 
SELECT
    last_name,
    job_id,
    salary,
    commission_pct
FROM
    employees
-- WHERE
--    commission_pct = NULL; -- 값이 아예 없기 떄문에 NULL은 비교연산자를 사용하지 못한다. /조건 자체의 오류 
-- WHERE
--     commission_pct IS NULL; --별도로 NULL인지 감별해주는 명령어! 이것을 사용하시오! 중요! 
WHERE
   nvl(commission_pct, -1) = -1;         -- INDEX 사용불가!!! /평이한 방법은 아님 


-- 6. IS NOT NULL 연산자
SELECT
    last_name,
    job_id,
    salary,
    manager_id
FROM
    employees
WHERE
    manager_id IS NOT NULL;

6. 연산자 우선순위

우선이 되어야하는 연산은 ()를 사용해 조절하자

-- ------------------------------------------------------
-- 연산자 우선순위 (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;

-- 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 ) 
    -- AND salary >= 4000
    -- AND salary <= 9000;

7. ORDER BY절의 오름차순과 내림차순

(이것을 사용하면 성능이 뚝 떨어지니 필요할 때만 사용하라)

-- ------------------------------------------------------
-- ORDER BY clause
-- ------------------------------------------------------
-- 문법)
--  SELECT [DISTINCT] {*, column [Alias], . . .}
--  FROM 테이블명
--  [ WHERE 조건식 ]
--  [ ORDER BY { column|표현식} [ASC|DESC] ];  // 기본이 ASC = 오름차순
-- ------------------------------------------------------

-- ------------------------------------------------------
-- 1. 숫자 데이터 정렬 = 꼭 필요할때만 사용해라 성능이 뚝 떨어진다.
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name,
    job_id,
    salary
FROM
    employees
-- ORDER BY
--    salary;           -- default: ASC (오름차순 정렬)
-- ORDER BY
--    salary ASC;       -- 오름차순 정렬 (ascending)
ORDER BY
    salary DESC;     -- 내림차순 정렬 (descending)  


-- ORDER BY 절에 별칭(alias) 사용
SELECT
    employee_id,
    last_name,
    job_id,
    salary + 100 AS "월급"
FROM
    employees
ORDER BY
   월급 DESC;            -- 컬럼별칭으로 정렬
-- ORDER BY
--     salary + 100 DESC;  -- 표현식으로 정렬


-- ORDER BY 절에 컬럼인덱스 사용
-- (주의) Oracle은 인덱스가 1부터 시작함을 명심할 것!!
SELECT
    employee_id,        -- 1
    first_name,         -- 2
    last_name,          -- 3
    job_id,             -- 4
    salary AS "월급"     -- 5
FROM
    employees
-- 다른 대안이 없는 경우에만 쓸 것!!!(부작용)
-- (SELECT절의 구성컬럼목록에 변경이 없다 라는 조건하에...)
ORDER BY
    4 DESC;    -- 컬럼인덱스로 정렬 = 문법적으로 가능하다 하더라도 이걸 쓰면 안됌 4라는 숫자가 명시하는 컬럼은 변경가능


-- ------------------------------------------------------
-- 2. 문자 데이터 정렬
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name AS 이름,
    job_id,
    salary
FROM
    employees
-- ORDER BY
--    last_name ASC;  -- 컬럼명으로 정렬
-- ORDER BY
--    이름 ASC;        -- 컬럼별칭으로 정렬 
ORDER BY
    2 ASC;          -- 컬럼인덱스로 정렬 = 이렇게 사용 말라!

SELECT * FROM dual;

-- ------------------------------------------------------
-- 3. 날짜 데이터 정렬
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name,
    salary,
    hire_date AS 입사일
FROM
    employees
ORDER BY
    hire_date DESC;     -- 컬럼명으로 정렬 = 표준 
ORDER BY
   입사일 DESC;          -- 컬럼별칭으로 정렬
-- ORDER BY
--    4 DESC;              -- 컬럼인덱스로 정렬


-- ------------------------------------------------------
-- 4. 다중컬럼 정렬
-- ------------------------------------------------------
-- 문법)
-- SELECT [DISTINCT] {*, column [Alias], . . .}
-- FROM 테이블명
-- [WHERE 조건식]
-- ORDER BY 
--  {column1|표현식1} [ASC|DESC], 
--  {column2|표현식2} [ASC|DESC];
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name,
    salary,
    hire_date
FROM
    employees
ORDER BY 
    salary DESC,        -- 컬럼명1로 내림차순 정렬 먼저 나온 컬럼의 정렬결과를 반영한다.
    hire_date;          -- 컬럼명2로 오름차순 정렬 반영되지 않음.


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


-- ------------------------------------------------------
-- 5. NULL값 정렬
-- ------------------------------------------------------
-- (주의) Oracle 에서 가장 큰 값은, NULL 값임!!!
--       (값이 없기 때문에, 값의 크기를 비교불가)
--       따라서, 내림차순 정렬시, 가장 큰 값이 NULL 이 우선!
-- ------------------------------------------------------
SELECT
    employee_id,
    last_name,
    commission_pct
FROM
    employees
ORDER BY
   commission_pct DESC;    -- 컬럼명으로 내림차순 정렬
-- ORDER BY
--     commission_pct ASC;

-- (주의) 관계형 데이터베이스의 테이블은, 수학의 집합과 동일
--  즉, 수학의 집합의 성질을 그대로 물려받음:
--       (1) 레코드의 순서를 보장하지 않음(즉, 무작위로 저장)
--       (2) 중복을 허용하지 않음
--           (단, 관계형 테이블은 중복행을 포함할 수는 잇으나
--            기본키(PK)가 지정되어있다면, 당연히 중복음 없음!)

1. 람다식의 생략조건 1


@FunctionalInterface
public interface MyFuncionalInterface {
	// 1. 매개변수가 없고 리턴값도 없는 추상메소드
	public abstract void method();
	
}// end interface

public class MyFuncionalInterfaceEx {

	public static void main(String[] args) {
		MyFuncionalInterface fi; 
		
		// void method(); ->(1) 매개변수선언부를 그대로 가져오라! (2) 중괄호블록 생성
		fi = ()->{
			
			System.out.println("함수적 인터페이스를 람다식을 통해 사용 ");
			
		};// 람다식을 이용한 , 함수적 인터페이스에 대한 "익명구현객체"의 형성

		
		fi.method(); // 인터페이스에 선언된 추상메소드 호출  -> 다형성 2
		
		
		System.out.println(">> fi: " + fi);
		//>> fi: ex1.MyFuncionalInterfaceEx$$Lambda$1/0x0000000800c00bf8@3a71f4dd
		// 람다라고 적힌 주소값에 형성
		
		
//		------
		
		
		//--람다식의 생략1 람다식의 실행블록의 실행문장을 1개로 줄입 
		
		fi = () -> {System.out.println("실행문이 하나야..?");};
		
		// 람다식의 실행블록안의 실행문장이 단 1개라면, 중괄호기호({}) 마저도 생략가능하다!
		fi = () -> System.out.println("그럼 중괄호 생략이 가능하다.");

		fi.method();
		
	} // main

} // end class

2. 람다식의 생략조건 2,3

@FunctionalInterface
public interface MyFuncionalInterface {
	// 2. 매개변수가 있고 리턴값이 없는 추상메소드
	public abstract void method(int x);
	
}// end interface
public class MyFuncionalInterfaceEX {

	public static void main(String[] args) {
		
		MyFuncionalInterface fi;

		// void method(int x)
		
		fi = (int x) ->{
			int result = x * 5 ; 
			System.out.println(result);
			
		}; // 람다식을 이용한 "익명구현객체"의 생성
		
		fi.method(2);
		

		// 람다식의 생략 2
		// 매개변수의 타입을 생략함. 인자의 타입을 읽어서 실행
		fi = (x) ->{ 
			int result = x * 5 ; 
			System.out.println(result);
			
		}; // 람다식을 이용한 "익명구현객체"의 생성
		
		fi.method(3);
		
		
		// 람다식의 생략 3
		// 매개변수가 하나뿐이면 소괄호도 생략 가능함.
		fi = x -> System.out.println(x * 5);  // 간단!
		
		fi.method(4);
		
		
	}// main

} //end class

3. 람다식의 생략조건 4

@FunctionalInterface
public interface MyFunctionalInterface {
	// 3. 매개변수가 복수로 있고 리턴값이 없는 추상메소드
	public abstract int method(int x,int y);
	
}// end interface
public class MyFunctionalInterfaceEx {

	public static void main(String[] args) {
		MyFunctionalInterface fi; 
		
		fi = new MyFunctionalInterface() {

			@Override
			public int method(int x, int y) {
				
				System.out.println("익명 구현 객체 method(x,y)");

				int result = x+ y;
				return result;
			} // method 
		}; // 익명구현객체 코딩 기법으로 구현객체 생성 


		
		System.out.println(fi.method(20,30));
		
		
		fi = (int x, int y) ->  {return x + y;}; // 람다식을 이용한 익명구현 객체 생성 
		System.out.println(fi.method(2, 5));
		
		// 람다식의 생략 4 
		// 중괄호 블럭안의 실행문장이 만일 , return 문장이면 return 키워드 마저도 생략가능!
		fi = (x,y)-> x+y; 
		System.out.println(fi.method(2, 5));
		
		
		
	} // main

} // end class
public class MyInterfaceImpl implements MyFunctionalInterface {

	@Override
	public int method(int x, int y) {
		System.out.println("함수적 인터페이스를 구현시킨 클래스가 존재함");
		System.out.println("몇 줄 안되는 버튼 같은 간단한 로직일 때만 람다로 해주세요");
		
		int result = x + y;

		return result ;
		
	} // method
} // end class
 

과제

람다로 구현하기

public class Assignment {
	public static void main(String[] args) {
		Assignment01 result1; 
		Assignment02 result2;
		Assignment03 result3;
		Assignment04 result4;
		
		result1 = (num1 , num2) -> num1 + num2 ;
		result2 = (num1, num2) -> System.out.println(num1 * num2) ;
		result3 =  (num1, num2) -> System.out.println(num1 - num2) ;
		result4 = number -> {
			for(int i=2;;i++) {
				if(i==number) {return true;}  
				if(number%i==0 || number==1 ) {           
					return false;
				}//if
			}// for
		};// result4
 
		System.out.println(result4.isPrimeNumber(20641));
		
		
		
	}// main
}// end class

소수 부분 알고리즘
2. 자기자신외에 수로 나누어지는지 확인
-나누어지면 소수가 아니다. false
3. 없으면 자기자신만 나눠 질 때 true를 반환

profile
일단 흐자

0개의 댓글