Study Web Development

11월 19일

이전으로

Oracle SQL

2. SQL(Standard Query Language)

2-3 SELECT문

WHERE절
SELECT ename, sal, sal*12 annsal FROM emp WHERE sal*12 BETWEEN 20000 AND 30000;
-- SELECT ename, sal, sal*12 annsal FROM emp WHERE annsal BETWEEN 20000 AND 30000;
-- 11) 이름에 A 또는 E가 포함되어 있는 모든 사원의 이름을 표시하시오.
SELECT ename FROM emp WHERE ename LIKE '%A%' OR ename LIKE '%E%';
-- 12) 관리자가 없는 모든 사원의 이름과 업무를 표시하시오.
SELECT ename, job, mgr FROM emp WHERE mgr IS NULL;
-- 13) 커미션 항목이 입력된 사원들의 이름과 급여, 커미션을 구하시오.
SELECT ename, sal, comm FROM emp WHERE comm IS NOT NULL;
ORDER BY절
SELECT * FROM emp ORDER BY sal; -- 기본값이 오름차순이라 키워드 생략 가능
SELECT * FROM emp ORDER BY sal ASC;
SELECT * FROM emp ORDER BY ename; -- 문자열의 경우 사전순 정렬
SELECT * FROM emp ORDER BY hiredate; -- 오래된 날짜순 정렬
SELECT * FROM emp ORDER BY sal DESC;
SELECT * FROM emp ORDER BY ename DESC;
SELECT * FROM emp ORDER BY hiredate DESC; -- 최근 날짜순 정렬
-- 정렬을 했을 때 중복값이 있으면 다른 컬럼으로 2차 정렬 가능
SELECT * FROM emp ORDER BY sal, ename;
SELECT empno, ename, sal*12 annsal FROM emp ORDER BY annsal;
-- (주의) 프로그래밍 언어의 인덱스는 0부터 시작하지만, 데이터베이스의 인덱스는 1부터 시작
SELECT ename, job, deptno, hiredate FROM emp ORDER BY 3; -- 3번째로 명시한 컬럼 deptno 기준으로 정렬
SELECT * FROM emp ORDER BY 2; -- 테이블의 컬럼이 생성된 숫자대로 컬럼 숫자 위치 부여
-- NULLS FIRST 또는 NULLS LAST 키워드를 사용하여 반환된 행 중 NULL값을 포함하는 행이 정렬 순서상 처음 또는 마지막에 나타나도록 지정 가능
SELECT * FROM emp ORDER BY comm NULLS FIRST;
SELECT * FROM emp ORDER BY comm DESC; -- 내림차순시 NULL 위치의 기본값은 FIRST
SELECT * FROM emp ORDER BY comm NULLS LAST;
SELECT * FROM emp ORDER BY comm; -- 오름차순시 NULL 위치의 기본값은 LAST
SELECT * FROM emp ORDER BY comm DESC NULLS LAST;
-- 오름차순, 내림차순 키워드는 NULL 위치 제어 키워드보다 선행해야 함
-- SELECT * FROM emp ORDER BY comm NULLS LAST DESC;
-- 1) 사원 번호, 사원 이름, 입사일을 출력하는데 입사일이 빠른 사람 순으로 정렬하시오.
SELECT empno, ename, hiredate FROM emp ORDER BY hiredate;
-- 2) 사원 이름, 급여, 연봉을 구하고 연봉이 많은 순으로 정렬하시오.
SELECT ename "사원 이름", sal 급여, sal*12 연봉 FROM emp ORDER BY 연봉 DESC;
-- 3) 10번 부서 또는 20번 부서에서 근무하고 있는 사원의 이름과 부서 번호를 출력하는데, 이름을 영문자순으로 표시하시오.
SELECT ename, deptno FROM emp WHERE deptno IN (10, 20) ORDER BY ename;
-- 4) 커미션 계약을 맺은 모든 사원의 이름, 급여, 커미션을 출력하는데 커미션을 기준으로 내림차순 정렬하시오.
SELECT ename, sal, comm FROM emp WHERE comm IS NOT NULL ORDER BY comm DESC;
함수
문자 조작 함수
-- LOWER : 소문자로 변경
SELECT LOWER('HELLO') FROM dual;
SELECT LOWER(ename) name, LOWER(job) job FROM emp;
-- UPPER : 대문자로 변경
SELECT UPPER('school') FROM dual;
-- INITCAP : 각 단어의 첫 글자는 대문자, 나머지는 소문자로 변경
SELECT INITCAP('hello wORLD') FROM dual;
SELECT INITCAP(ename) name, INITCAP(job) job FROM emp;
-- 문자열1과 문자열2를 연결하여 하나의 문자열로 반환
SELECT CONCAT('Hello', 'World') FROM dual;
SELECT CONCAT(ename, job) FROM emp;
-- SUBSTR(대상 문자열, 인덱스) : 대상 문자열에서 지정한 인덱스부터 끝까지 문자열을 추출
SELECT SUBSTR('Hello World', 3) FROM dual; -- 세 번째 문자인 l부터 끝까지 추출
SELECT SUBSTR('Hello World', -3) FROM dual; -- 끝에서부터 세 번째 문자인 r부터 끝까지 추출
-- SUBSTR(대상 문자열, 인덱스, 길이) : 대상 문자열에서 지정한 인덱스부터 지정한 길이의 문자열을 추출
SELECT SUBSTR('Hello World', 3, 3) FROM dual; -- 세 번째 문자인 l부터 문자를 3개 추출
SELECT SUBSTR('Hello World', -3, 2) FROM dual; -- 끝에서부터 세 번째 문자인 r부터 문자를 2개 추출
-- 대상 문자열의 길이를 반환
SELECT LENGTH('Hello World') FROM dual;
SELECT ename, LENGTH(ename) FROM emp;
-- 검색 문자의 위치값 반환
-- (주의) 검색 문자가 없을 경우 0 반환
SELECT INSTR('Hello World', 'e') FROM dual;
SELECT INSTR('Hello World', 'E') FROM dual;
SELECT INSTR('Hello World', 'o') FROM dual; -- 처음으로 등장하는 'o'의 위치값 반환
SELECT INSTR('Hello World', 'o', 6) FROM dual; -- 검색 인덱스를 입력하면 해당 위치부터 검색하여 처음으로 등장하는 'o'의 위치값 반환
SELECT INSTR('Hello World', 'o', 1, 2) FROM dual; -- 검색 인덱스와 반복 횟수 n을 입력하면 해당 위치부터 검색하여 n번째 등장하는 'o'의 위치값 반환
-- LPAD(대상 문자열, 총 길이, 문자) : 총 길이를 지정하여 대상 문자열을 표시하고 남는 공간의 왼쪽에 지정한 문자를 표시
SELECT LPAD('Hello', 10, '*') FROM dual;
-- RPAD(대상 문자열, 총 길이, 문자) : 총 길이를 지정하여 대상 문자열을 표시하고 남는 공간의 오른쪽에 지정한 문자를 표시
SELECT RPAD('Hello', 10, '#') FROM dual;
-- 문자열에서 공백이나 특정 문자를 제거하여 반환
-- 제거 방향이 왼쪽이면 LEADING, 오른쪽이면 TRAILING, 양쪽이면 BOTH 키워드 지정
SELECT TRIM('h' FROM 'habchh') FROM dual; -- 제거 방향의 기본값이 BOTH라 키워드 생략 가능
SELECT TRIM(BOTH 'h' FROM 'habchh') FROM dual;
SELECT TRIM(LEADING 'h' FROM 'habchh') FROM dual;
SELECT TRIM(TRAILING 'h' FROM 'habchh') FROM dual;
-- LTRIM(대상 문자열, 제거할 문자) : 대상 문자열의 왼쪽에서 지정한 문자를 제거하여 반환
SELECT LTRIM('habchh', 'h') FROM dual;
-- RTRIM(대상 문자열, 제거할 문자) : 대상 문자열의 오른쪽에서 지정한 문자를 제거하여 반환
SELECT RTRIM('habchh', 'h') FROM dual;
-- 대상 문자열에서 옛 문자를 새 문자로 대체
SELECT REPLACE('010.1234.5678', '.', '-') FROM dual;
SELECT ename, LOWER(SUBSTR(ename, 1, 3)) FROM emp;
-- 1) 업무를 첫 글자는 대문자로, 나머지는 소문자로 출력하시오.
SELECT INITCAP(job) FROM emp;
-- 2) 사원 이름 중 A가 포함된 사원 이름을 구하고, 그 이름을 앞에서 3자만 추출하여 출력하시오.
SELECT SUBSTR(ename, 1, 3) FROM emp WHERE ename LIKE '%A%';
-- 3) 이름의 세 번째 문자가 A인 모든 사원의 이름을 표시하시오.
SELECT ename FROM emp WHERE ename LIKE '__A%';
SELECT ename FROM emp WHERE SUBSTR(ename, 3, 1)='A';
-- 4) 이름이 J 또는 A 또는 M으로 시작하는 모든 사원의 이름(첫 글자는 대문자로, 나머지는 소문자로 표시) 및 이름의 길이를 표시하시오. (alias는 name과 legth로 표시)
SELECT INITCAP(ename) "name", LENGTH(ename) "length" FROM emp
WHERE ename LIKE 'J%' OR ename LIKE 'A%' OR ename LIKE 'M%';
-- SQL에서 LIKE와 IN을 동시에 사용할 수는 없으며, RDBMS마다 문법이 조금씩 다르긴 하지만 CONTAINS 함수로 대체 가능
-- SELECT INITCAP(ename) "name", LENGTH(ename) "length" FROM emp
-- WHERE ename LIKE IN ('J%', 'A%', 'M%');
SELECT INITCAP(ename) "name", LENGTH(ename) "length" FROM emp
WHERE SUBSTR(ename, 1, 1) IN ('J', 'A', 'M');
-- 5) 이름의 글자 수가 6자 이상인 사원의 이름을 소문자로 출력하시오.
SELECT LOWER(ename) FROM emp WHERE LENGTH(ename)>=6;
-- 6) 이름의 글자 수가 6자 이상인 사람의 이름을 앞에서 3자만 구하여 소문자로 출력하시오.
SELECT SUBSTR(LOWER(ename), 1, 3) FROM emp WHERE LENGTH(ename)>=6;
숫자 함수
-- 올림 처리한 정수값을 반환
SELECT CEIL(1.4) FROM dual;
-- 버림 처리한 정수값을 반환
SELECT FLOOR(1.7) FROM dual;
-- 나머지값 반환
SELECT MOD(17, 2) FROM dual; -- % 연산자 사용 불가
-- 반올림
SELECT ROUND(45.926) FROM dual; -- 자릿수를 지정하지 않으면 소수점 이하 첫째 자리에서 반올림
SELECT ROUND(45.926, 2) FROM dual; -- 소수점 이하 셋째 자리에서 반올림하여 소수점 이하 둘째 자리까지 표시
SELECT empno, ename, sal, ROUND(sal*1.15) "New Salary" FROM emp;
-- 절사
SELECT TRUNC(45.926) FROM dual; -- 자릿수를 지정하지 않으면 소수점 이하 첫째 자리에서 절사
SELECT TRUNC(45.926, 2) FROM dual; -- 소수점 이하 셋째 자리에서 절사하여 소수점 이하 둘째 자리까지 표시

자바

과제

  1. 새 패키지 kr.s06.score 생성하고 새 클래스 Score 생성
package kr.s06.score;

public class Score {
	/*
	 * [실습] 이름(name), 국어(korean), 영어(english), 수학(math)
	 * 총점 구하기(int makeSum), 평균 구하기(double makeAvg), 등급 구하기(String makeGrade)
	 */
	private String name;
	private int korean;
	private int english;
	private int math;

	// 총점 구하기
	public int makeSum() {
		return korean + english + math;
	}
	// 평균 구하기
	public double makeAvg() {
		return makeSum() / 3.0;
	}
	// 등급 구하기
	public String makeGrade() {
		String str;
		switch((int)(makeAvg()/10)) {
		case 10:
		case 9: str = "A"; break;
		case 8: str = "B"; break;
		case 7: str = "C"; break;
		case 6: str = "D"; break;
		default: str = "F";
		}
		return str;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getKorean() {
		return korean;
	}
	public void setKorean(int korean) {
		this.korean = korean;
	}
	public int getEnglish() {
		return english;
	}
	public void setEnglish(int english) {
		this.english = english;
	}
	public int getMath() {
		return math;
	}
	public void setMath(int math) {
		this.math = math;
	}

	@Override
	public String toString() { // 성적 출력 및 파일 생성에 활용할 수 있도록 toString() 메서드를 재정의
		return String.format("%s\t%d\t%d\t%d\t%d\t%.2f\t%s%n", name, korean, english, math, makeSum(), makeAvg(), makeGrade()); // String의 static 메서드인 format() 메서드를 이용하여 printf() 메서드처럼 포맷문자를 적용한 문자열 반환
	}
}
  1. 새 클래스 ScoreMain 생성
package kr.s06.score;

import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public class ScoreMain {
	BufferedReader br;
	ArrayList<Score> list;

	public ScoreMain() {
		list = new ArrayList<Score>();
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			callMenu();
		}
		catch(IOException e) {
			e.printStackTrace();
		}
		finally {
			if(br!=null) try {br.close();} catch(IOException e) {}
		}
	}

	// 메뉴
	public void callMenu() throws IOException {
		while(true) {
			System.out.println("메뉴 : 1. 성적 입력, 2. 성적 출력, 3. 파일 생성, 4. 파일 읽기, 5. 종료");
			System.out.print("메뉴 > ");
			try {
				int num = Integer.parseInt(br.readLine());
				if(num == 1) {
					input();
				}
				else if(num == 2) {
					output();
				}
				else if(num == 3) {
					createFile();
				}
				else if(num == 4) {
					readFile();
				}
				else if(num == 5) {
					System.out.println("프로그램 종료");
					break;
				}
				else {
					System.out.println("잘못 입력했습니다.");
				}
			}
			catch(NumberFormatException e) {
				System.out.println("숫자만 입력 가능!");
			}
		}
	}
	// 성적 입력
	public void input() throws IOException {
		Score s = new Score();
		System.out.print("이름 > ");
		s.setName(br.readLine());
		s.setKorean(parseInputData("국어 > "));
		s.setEnglish(parseInputData("영어 > "));
		s.setMath(parseInputData("수학 > "));
		list.add(s); // Score 객체를 ArrayList에 저장
	}
	// 성적 범위 체크(0~100)
	public int parseInputData(String course) throws IOException {
		while(true) {
			System.out.print(course);
			try {
				int num = Integer.parseInt(br.readLine());
				if(num < 0 || num > 100) {
					throw new ScoreValueException("0~100 사이의 값만 인정");
				}
				return num;
			}
			catch(NumberFormatException e) {
				System.out.println("숫자만 입력하세요.");
			}
			catch(ScoreValueException e) {
				System.out.println(e.getMessage());
			}
		}
	}
	// 성적 출력
	public void output() {
		if(list.size()>0) {
			System.out.println("이름\t국어\t영어\t수학\t총점\t평균\t등급");
			for(Score s : list) {
				System.out.print(s); // 재정의된 toString() 메서드가 %n 포함하고 있으므로 print() 메서드 사용
			}
		}
		else {
			System.out.println("출력할 성적이 없습니다.");
		}
	}
	// 파일 생성
	public void createFile() {
		FileWriter fw = null;
		try {
			fw = new FileWriter("score.txt");
			fw.write("이룸\t국어\t영어\t수학\t총점\t평균\t등급\n");
			for(Score s : list) {
				fw.write(s.toString()); // s만 명시하면 Score 자료형으로 인식해서 컴파일 에러
			}
			fw.flush();
			System.out.println("파일이 생성되었습니다.");
		}
		catch(IOException e) {
			System.out.println("파일 생성 오류");
		}
		finally {
			if(fw!=null) try {fw.close();} catch(IOException e) {}
		}
	}
	// 파일 읽기
	public void readFile() {
		FileReader fr= null;
		int readChar;
		try {
			fr = new FileReader("score.txt");
			while((readChar = fr.read())!=-1) {
				System.out.print((char)readChar);
			}
		}
		catch(FileNotFoundException e) {
			System.out.println("생성된 파일이 없습니다.");
		}
		catch(IOException e) {
			System.out.println("파일 읽기 오류");
		}
		finally {
			if(fr!=null) try {fr.close();} catch(IOException e) {}
		}
	}
	public static void main(String[] args) {
		/*
		 * [실습]
		 * 메뉴 : 1. 성적 입력, 2. 성적 출력, 3. 파일 생성, 4. 파일 읽기, 5. 종료
		 * 파일 생성에는 FileOutputStream, FileWriter 중 하나를 이용
		 * 파일 읽기에는 FileInputStream, FileReader 중 하나를 이용
		 */
		new ScoreMain();
	}
}
  1. 새 클래스 ScoreValueException 생성
package kr.s06.score;

public class ScoreValueException extends Exception {
	// 사용자 정의 예외 클래스
	public ScoreValueException(String message) {
		super(message);
	}
}

다음으로