가. 하나 이상의 행을 반환
나. 메인쿼리에서 사용가능한 연산자는 아래와 같음:
(1) IN : 메인쿼리와 서브쿼리가 IN 연산자로 비교수행.
서브쿼리 결과값이 복수 개인 경우에 사용.
(2) ANY : 서브쿼리에서, > 또는 < 같은 비교 연산자를 사용하고자
할 때 사용. 검색조건이 하나라도 일치하면 참.
(3) ALL : 서브쿼리에서 > 또는 < 같은, 비교 연산자를 사용하고자
할 때 사용. 검색조건의 모든 값이 일치하면 참.
(4) EXISTS : 서브쿼리의 반환값이 존재하면, 메인쿼리를 실행하고,
반환값이 없으면 메인쿼리를 실행하지 않음.
-- 'Whalen' or 'Fay'와 동일한 월급여를 받는 사원조회
SELECT
last_name,
salary
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로,
-- 복수 값과 연산가능한 연산자 사용가능 (IN)
-- salary IN ( 1000, 2000 )
salary IN (
-- 복수행에 단일행 연산자 사용한 경우:
-- ORA-01427: single-row subquery returns more than one row
-- salary = (
-- 복수 행 비상관 서브쿼리: 'Whalen' 와 'Fay' 월급여 반환
-- 메인쿼리로 결과값 전달
SELECT salary
FROM employees
WHERE last_name IN ('Whalen', 'Fay')
);
-- 월급여를 13000 보다 많이 받는 부서에 속한 모든 사원 조회
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로,
-- 복수 값과 연산가능한 연산자 사용가능 (IN)
-- department_id IN ( 100, 200 )
department_id IN (
-- 복수 행 비상관 서브쿼리: 월급여 > 13000인 사원목록 반환
-- 메인쿼리로 결과값 전달
SELECT
department_id
FROM
employees
WHERE
salary > 13000
);
-서브쿼리가 반환한 값 중 모든 값이 만족하게 반환
-ALL 모든 데이터를 최소값보다 작거나 최대값보다 큼을 만족 할 때 반환
가. 서브쿼리 반환값이 복수 개.
나. 메인쿼리에서, < or > 같은 비교연산자 사용하고자 할 때 사용.
다. 메인쿼리의 비교연산자는 단일 행 연산자이기 때문에,
메인쿼리의 복수행 연산자에 ALL 키워드 없이 사용하면 오류발생.
라. ALL 연산자:
서브쿼리에서 반환된 전체 행들에 대해서, 조건이 모두(all)
만족해야 된다는 것을 의미.
마. 구분:
(1) > ALL (서브쿼리)
- 서브쿼리에서 반환된 모든 데이터보다 큰 데이터 조회
- 결국, 서브쿼리에서 반환된 모든 데이터 중,
*최대값보다 큰* 데이터 조회
(2) < ALL (서브쿼리)
- 서브쿼리에서 반환된 모든 데이터보다 작은 데이터 조회
- 결국, 서브쿼리에서 반환된 모든 데이터 중,
*최소값보다 작은* 데이터 조회
-- 직책이 IT_PROG인 사원 월급 조회
SELECT
salary
FROM
employees
WHERE
job_id = 'IT_PROG'
ORDER BY
1 ASC;
-- 직책이 IT_PROG인 사원의 월급보다 작은 사원 정보 조회
메인쿼리1: 복수행 서브쿼리가 사용되었으므로, 복수 값과 연산가능한 연산자 사용가능. 아래조건은, 단일 값 연산자인 비교연산자(<) 사용 --> *오류발생* 왜? 오라클 입장에서는, 여러 월급 중에서, 과연 어떤 월급보다 작아야 하는지 판단할 수 없기 때문. ORA-01427: single-row subquery returns more than one row salary < ( 메인쿼리2: 복수행 서브쿼리가 사용되었으므로, 복수 값과 연산가능한 연산자 사용가능. 아래조건은, 단일값 연산자인 비교연산자(<) 사용 --> *오류발생* 가능하나, 오라클이 반환된 여러 월급 중에서, 가장 작은(최소 급여) 급여를 기준으로, 메인쿼리 조건을 수행가능하도록 ALL 키워드 적용. 결과적으로, 복수행 서브쿼리가 반환한 모든 값 중, *최소값 보다 작은* 사원 필터링
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
salary < ALL (
-- 복수 행 비상관 서브쿼리: 직책이 IT_PROG인 사원의 월급 반환
-- 메인쿼리로 결과값 전달
SELECT
salary
FROM
employees
WHERE
job_id = 'IT_PROG'
);
-- 직책이 IT_PROG인 사원의 월급보다 많은 사원 정보 조회
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로, 복수 값과 연산가능한 연산자 사용가능.
--
-- 아래조건은, 단일값 연산자인 비교연산자(>) 사용 --> *오류발생* 가능하나,
-- 오라클이 반환된 여러 월급 중에서, 가장 큰(최대 급여) 급여를 기준으로,
-- 메인쿼리 조건을 수행가능하도록 ALL 키워드 적용
--
-- 결과적으로, 복수행 서브쿼리가 반환한 모든 값 중, *최대값 보다 큰* 사원 필터링
salary > ALL (
-- 복수 행 비상관 서브쿼리: 직책이 IT_PROG인 사원의 월급 반환
-- 메인쿼리로 결과값 전달
SELECT
salary
FROM
employees
WHERE
job_id = 'IT_PROG'
);
-서브쿼리가 반환한 값 중 하나의 값이 만족하게 만족하면 반환
-ANY 모든데이터들이 최소값보다 크거나 최대값보다 작은 데이터를 만족 할 때 반환
ALL은 ANY의 집한안의 집합이라 할 수있다.
가. 서브쿼리 반환값이 복수 개.
나. 서브쿼리에서, < or > 같은 비교연산자 사용하고자 할 때 사용.
다. 메인쿼리의 비교연산자는 단일 행 연산자이기 때문에,
메인쿼리의 단일행 연산자에 ANY 키워드 없이 사용하면 오류발생.
라. ANY 연산자:
서브쿼리에서 반환된 전체 행들에 대해서, 조건이 하나라도(any)
만족해야 된다는 것을 의미.
마. 구분:
(1) > ANY (서브쿼리)
- 서브쿼리에서 반환된 모든 데이터보다 큰 데이터 조회
- 결국, 서브쿼리에서 반환된 모든 데이터 중,
*최소값보다 큰* 데이터 조회
(2) < ANY (서브쿼리)
- 서브쿼리에서 반환된 모든 데이터보다 작은 데이터 조회
- 결국, 서브쿼리에서 반환된 모든 데이터 중,
*최대값보다 작은* 데이터 조회
-- 직책이 IT_PROG인 사원의 최소 월급여보다 큰 사원 정보 조회
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로, 복수 값과 연산가능한 연산자 사용가능.
--
-- 아래조건은, 단일값 연산자인 비교연산자(>) 사용 --> *오류발생* 가능하나,
-- 오라클이 반환된 여러 월급 중에서, 가장 작은(최소 급여) 급여를 기준으로,
-- 메인쿼리 조건을 수행가능하도록 ANY 키워드 적용
--
-- 결과적으로, 복수행 서브쿼리가 반환한 모든 값 중, *최소값 보다 큰* 사원 필터링
salary > ANY (
-- 복수 행 비상관 서브쿼리: 직책이 IT_PROG인 사원의 월급 반환
-- 메인쿼리로 결과값 전달
SELECT
salary
FROM
employees
WHERE
job_id = 'IT_PROG'
);
-- 직책이 IT_PROG인 사원의 최대 월급여보다 작은 사원 정보 조회
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로, 복수 값과 연산가능한 연산자 사용가능.
--
-- 아래조건은, 단일값 연산자인 비교연산자(<) 사용 --> *오류발생* 가능하나,
-- 오라클이 반환된 여러 월급 중에서, 가장 큰(최대 급여) 급여를 기준으로,
-- 메인쿼리 조건을 수행가능하도록 ANY 키워드 적용
--
-- 결과적으로, 복수행 서브쿼리가 반환한 모든 값 중, *최대값 보다 작은* 사원 필터링
salary < ANY (
-- 복수 행 비상관 서브쿼리: 직책이 IT_PROG인 사원의 월급 반환
-- 메인쿼리로 결과값 전달
SELECT
salary -- 이 값이 만일, 1000, 2000, 3000 을 반환한다면
FROM
employees
WHERE
job_id = 'IT_PROG'
);
-EXISTS 단항연산자/ 서브쿼리의 반환결과 조건에 따라 단 하나의 조건이라도 충족한다면 메인쿼리를 전부 반환한다. 단 하나의 조건이라도 만족하지 않으면 메인쿼리를 수행은 하지만 하나도 반환이 안됌.
(WHERE절은 조건에 맞춰 뽑는다. 조건을 극단적으로 만들어줌 )
가. 서브쿼리 반환값이 복수 개.
나. 메인쿼리의 값이, 서브쿼리에서 반환된 결과 중에 하나라도
존재하는지 여부를 확인할 때 사용하는 복수행 연산자.
다. 만일, 서브쿼리의 반환결과가 하나라도 없으면(false),
메인쿼리를 수행하지 않음.
라. 만일, 서브쿼리의 반환결과가 하나라도 있으면(true),
메인쿼리를 수행.
SELECT
last_name,
department_id,
salary,
commission_pct
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로, 복수값과 연산가능한 연산자 사용가능.
-- 복수행 연산자로 EXISTS 사용
--
-- 모든 사원조회 (if 커밋션을 받는 사원이 한명이라도 있다면...)
EXISTS (
-- 복수행 비상관 서브쿼리: 커밋션을 받는 사원번호 반환
-- 메인쿼리로 결과값 전달
SELECT
employee_id --NULL이어도 where절에 충족하는 NULL이라는 속성으로 35개반환
FROM
employees
WHERE
commission_pct IS NOT NULL
);
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
-- 모든 사원조회 (if 5000000보다 큰 월급여를 받는 사원이 한명이라도 있다면...)
EXISTS (
-- 복수 행 비상관 서브쿼리: 월급여가 500000보다 큰 사원번호 반환 (*없음*)
-- 메인쿼리로 결과값 전달(하나도 조회된 결과가 없으므로, false가 전달)
SELECT 1 --where에 충족하는 열이 무슨 이름으로 해도나옴
FROM employees
WHERE salary > 500000
);
가. 서브쿼리에서, 여러 컬럼을 조회하여 반환
나. 메인쿼리의 조건절에서는, 서브쿼리의 여러 컬럼의 값과 일대일
매칭되어 조건판단을 수행해야 함.
다. 메인쿼리의 조건판단방식에 따른 구분:
(1) Pairwise 방식
컬럼을 쌍으로 묶어서, 동시에 비교
(2) Un-pairwise 방식
컬럼별로 나누어 비교, 나중에 AND 연산으로 처리
SELECT
last_name,
department_id,
salary
FROM
employees
WHERE
-- 메인쿼리: 복수행 서브쿼리가 사용되었으므로, 복수 값과 연산가능한 연산자 사용가능 (IN)
--
-- 컬럼을 쌍으로 묶어서, 동시에 비교 (**Pairwise 방식**)
-- 동시에 만족하는 경우에만 참(true)으로 판단.
--
-- 결과적으로, 부서별로 가장 많은 월급여를 받는 사원정보 조회
( department_id, salary ) IN (
-- 복수 행 비상관 서브쿼리: 각 부서별, 최대 월급여 반환
-- 메인쿼리로 결과값 전달
SELECT
department_id,
max(salary)
FROM
employees
GROUP BY
department_id -- NULL 그룹도 포함!!
)
ORDER BY
2 ASC;
-진짜 쓰는 컬럼 등등 만을 이용해 진짜 필요한 결과셋을 만들어 작은 테이블로 재정의 하는 것/ 크기를 줄여 효율적 구성을 돕는다.
-반드시 별칭을 지어야함.
가. 뷰(View) : 실제 존재하지 않는 가상의 테이블이라 할 수 있음
나. FROM 절에 사용된 서브쿼리를 의미
다. 동작방식이 뷰(View)와 비슷하여 붙여진 이름
라. 일반적으로, FROM 절에는 테이블이 와야 하지만, 서브쿼리가
마치 하나의 가상의 테이블처럼 사용가능
마. 장점:
실제로 FROM 절에서 참조하는 테이블의 크기가 클 경우에,
필요한 행과 컬럼만으로 구성된 집합(Set)을 재정의하여,
쿼리를 효율적으로 구성가능.
-- 각 부서별, 총 사원수 / 월급여 총계 / 월급여 평균 조회
-- Oracle Inner Join( Equal Join ) 사용방식
SELECT
e.department_id,
sum(salary) AS 총합,
avg(salary) AS 평균,
count(*) AS 인원수
FROM
-- CROSS JOIN(== Cartesian Product) Size: 107 x 27 = 2,889
employees e,
departments d
WHERE
e.department_id = d.department_id
GROUP BY
e.department_id
ORDER BY
1 ASC;
-- 위 조인 쿼리를, 좀 더 효율적으로 수행가능한 형식으로 변경
-- 인라인 뷰(Inline View) 사용
SELECT
e.department_id,
d.department_name,
총합,
평균,
인원수
FROM
-- CROSS JOIN(== Cartesian Product) Size: 12 x 27 = 324
( -- 인라인 뷰(Inline View) 크기: 12
SELECT
department_id,
sum(salary) AS 총합,
avg(salary) AS 평균,
count(*) AS 인원수
FROM
employees
GROUP BY
department_id
) e,
departments d -- 부서크기: 27
WHERE
e.department_id = d.department_id -- 조인조건(공통컬럼지정)
ORDER By
1 ASC;
어떤 컬렉션프레임워크를 이용하여 구현할까 고민하는것이 중요함
특징
1)인덱스로 관리
2)중복해서 객체로 저장하능
----<List간편사용메소드>---------
public class AsListEx {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("홍길동","신용권","백자바");
for(String name: list1) {
System.out.println(name);
}// enhanced for
// ----
// 기본타입의 값을, List 컬렉션으로 관리하고 싶으면,
// 기본타입에 대응되는 Wrapper Type Class를 사용하라!!
List<Integer> list2 = Arrays.<Integer>asList(1,2,3,4,5,6,7);
for(int value : list2) {
System.out.println(value);
}// enhanced for
}// main
} // end class
-----------<ArrayList 와 List계열 성질>
public class ArrayListEx {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
// --
list.add("Java");
list.add("JDBC");
list.add("Servlet/JSP");
list.add(2,"Database"); // 2번째로 넣으면서 나머지를 뒤로 한칸씩 미룬다. 많으면 많을수록 시간이 늘어난다. 엄청나게 많으면 치명적
list.add("MyBATIS");
System.out.println(list);
//결과: [Java, JDBC, Database, Servlet/JSP, MyBATIS]
// --
int size = list.size();
System.out.println("총 객체수: " + size);
// 결과: 총 객체수: 5
// ---
String skill = list.get(2);
System.out.println("2: " + skill);
//결과 2: Database
// ----
for(int i = 0 ; i < list.size();i++) {
String str = list.get(i);
System.out.println(i + ":" + str);
} // for
// 결과
// 0:Java
// 1:JDBC
// 2:Database
// 3:Servlet/JSP
// 4:MyBATIS
for(String str:list) { //Iterable 해야지 enhanced for문 사용가능 -> interface가 정의 되어있는지 찾아봐라
System.out.println(str);
} // enhanced for
//결과
// Java
// JDBC
// Database
// Servlet/JSP
// MyBATIS
list.remove(2);
list.remove(2); //지정된 index 요소 삭제
list.remove("IBATIS");
System.out.println(list); //결과: [Java, JDBC, MyBATIS]
list.clear();
list= null;
}//main
}// end class
@AllArgsConstructor
public class Board {
String subject;
String content;
String writer;
}// end class
// 데이터를 밀고 땡기고는 ArrayList와 동일/ Thread 부분만 다름
public class VectorEx {
public static void main(String[] args) {
@Cleanup("clear") // 별도로 지정해주면 이 문장의 끝을 만날때 해당 명시된 메소드로 실행해줌.
List<Board> list = new Vector<>();
list.add(new Board("제목1", "내용1", "글쓴이1"));
list.add(new Board("제목2", "내용2", "글쓴이2"));
list.add(new Board("제목3", "내용3", "글쓴이3"));
list.add(new Board("제목4", "내용4", "글쓴이4"));
list.add(new Board("제목5", "내용5", "글쓴이5"));
System.out.println(list);
//try-with-resource block은 반드시, 자원객체가 AutoCloseable 인터페이스를 구현하고 있어야한다
// List 컬렉션은 사용 불가하다.
// try(list){
// ;;
// }// try- with- resources
}// main
} // end class
순서 유지 하지 않고
중복 저장 안된다.
키와 값의 쌍으로 저장
키는 중복 저장이 안된다.