오늘 할일
3. 고급 웹 프로그래밍 공부 끝
3. 모든 과제(데이터베이스, 고급웹프로그래밍) 제출
4. 랜섬웨어 개발 5주차_멀티스레딩 및 플로우차트 기반으로 클라이언트와 서버 프로그램 분리
오늘 한일
1. 자바공부 끝
Q1. 왜 long은 리터럴 안붙여도 되는지
Q2. Scanner의 nextLine()사용 시 다음 데이터를 입력받아야 종료되는 이유
Q3. 교재의 logger.finnest(throw new Exception());오류. 올바른 사용법은?
Q4. ConsoleHandler의 역활과 logger.setLevel()의 역활
setLevel이상의 레벨만 로깅을 하는 것인가? logger.addHanlder에 ConsoleHandler를 넣는데, logger에서 기본적으로 처리되는 handler외의 것을 추가하여 전달하는 것인가
ConsoleHandler부분을 뺐더니 맨 아래 Shutdown 로깅 메시지가 출력되지 않았다. 찾아보니 모든 로깅 메세지를 콘솔에 출력한다고 하는데 없애고도 출력되는 이유.
Q5. abstract void bark(); void bark(){}가능, void bark(); abstract void bark(){} 불가능한 이유?
생각을 조금만 더 해보자. abstract 클래스는 상속을 받아야 인스턴스화 가능한 클래스다.
abstract void bark();는 현 추상 클래스를 상속 받을 때 override후 사용가능하다.
void bark(){}는 그냥 상속 후 사용이 가능하다
void bark();는 선언부가 존재하지 않아 서브에서라도 구현해야하는데 그럼 abstract를 붙이는게 맞다
abstract void bark(){}는 상속이후 구현되어야하는데 저게 가능해지면 서브에서 이미 구현된 것으로 처리되어 구현을 강제하지 않을 수 있다.
여서인가..?
우선 햇갈리는 개념은 Abstract클래스 내부 항목(속성, 메서드)들이 모두 Abstract속성을 가지는 게 아니라 명시적으로 지정이 가능한 것 같다. 우선 자바에서는 하나 이상의 abstract메서드를 가지는 클래스를 abstract클래스라고 한다. 햇갈리는 내용을 찾아버렸다. Abstract라고 모두 구현이 필요한 것이 아니다. 모두 구현이 필요한 것은 interface이다(default 메서드, static 메서드 제외). 일부만 구현하면 된다.
2. 데이터베이스 공부
Q1. 4주차p.144에서 20대 학생만을 대상으로 나이별 학생수를 검색하시오. 에서 나는 답을
SELECT 나이, COUNT(*) AS '나이별 학생수' FROM 학생 GROUBP BY 나이 HAVING 나이>=20 AND 나이<30;
으로 했는데 교재에서는 HAVING조건을 WHERE로 썼다. GROUP BY속성에 대한 조건은 HAVING에 써야된다고 생각하는데 둘 다 맞는건지 아니면 WHERE가 애매모호한건지 궁금.
HAVING->WHERE 그리고 WHERE->HAVING의 변환이 가능한지 그 개념도 궁금.
생각해보면 우선 가설을 세워보자.
가설 1) HAVING->WHERE이 가능하다.
예시1. 그룹별로 처리해야하는 값이 단순히 조건을 만족하는 값을 찾는 경우
SELECT 나이, COUNT() FROM 학생 GROUP BY 나이 HAVING 나이>=20;
는 나이가 20이상인 그룹별로 나눈 뒤 학생수를 계산한다.
SELECT 나이, COUNT() FROM 학생 WHERE 나이>=20 GROUP BY 나이;
는 나이가 20이상인 학생들에 대해 나이별로 그룹을 나눈 뒤 학생 수를 계산한다.
반례 1. 그룹별로 처리해야하는 집계함수 값의 경우 WHERE절에서 처리할 수 없다.
예시. SELECT COUNT() AS 제품개수, MAX(단가) AS 최고가 FROM 제품 GROUP BY 제조업체 HAVING COUNT() >= 3;
다음은 제조업체 별 항목이 3개 이상인 그룹에 대해 제품개수와 최고가를 출력한다. HAVING의 조건은 제조업체를 그룹으로 했을 때 개수정보 비교이기에 그냥 WHERE에 넣으면 전체 인스턴스 개수에 대한 조건이 된다. 만약 WHERE절로 조건을 옮긴다면 아래와 같다.
SELECT COUNT() AS 제품개수, MAX(단가) AS 최고가 FROM 제품 WHERE COUNT() >= 3 GROUP BY 제조업체;
다음은 전체 튜플의 개수가 3이상이라면 제품에 대해 제조업체별로 그룹화하여 제품개수와 최고가를 출력한다. 그런데 막상 비슷한 SQL을 만들어 실제 실행해보니 실행이 되지 않는다.
SELECT 나이, COUNT() AS '나이별 학생수' FROM 학생 WHERE COUNT()>1;
SELECT 나이, COUNT() AS '나이별 학생수' FROM 학생 WHERE COUNT()>1 AND 나이>=20 AND 나이<30 GROUP BY 나이;
두가지 SQL이 실행자체가 안되는데, Invalid use of GROUP function이라는 에러가 뜬다.
GROUP BY가 없는 앞의 SQL역시 같은 에러가 발생한다.
결론1) HAVING->WHERE이 되는 것도 있고 안되는 것도 있다.
여기서 파생된 두번째 가설
가설2) WHERE절에 집계함수가 있으면 오류가 발생한다.
예시1. SELECT 나이 FROM 학생 WHERE 30>MAX(나이); 오류
예시2. SELECT 나이 FROM 학생 WHERE 30>나이; 잘 실행
예시3. SELECT 나이 FROM 학생 WHERE 30>AVG(나이); 오류
반례) 아직 못찾음
결론2) WHERE절에 집계함수가 있으면 오류가 발생한다.
두가지 결론을 조합하여 가설3) HAVING절에 집계함수가 없다면 WHERE절로 표현이 가능하다
예시1. 집계함수를 가지는 HAVING
SELECT 소속학과, COUNT() AS 학생수 FROM 학생 GROUP BY 소속학과 HAVING COUNT()>1;
SELECT 소속학과, COUNT() AS 학생수 FROM 학생 WHERE COUNT()>1 GROUP BY 소속학과; 오류발생!
예시2. 집계함수를 가지지 않는 HAVING
SELECT 소속학과, COUNT() AS 학생수 FROM 학생 GROUP BY 소속학과 HAVING 소속학과 IN ('정보통신', '컴퓨터');
SELECT 소속학과, COUNT() AS 학생수 FROM 학생 GROUP BY 소속학과 HAVING 소속학과 IN ('정보통신', '컴퓨터');
결론3: HAVING->WHERE로의 변환은 가능하며, HAVING절에서 집계함수를 사용하지 않는 경우에만 변환되고 HAVING절에서 집계함수를 사용한다면 HAVING->WHERE로의 변환이 불가능하다.
결론3을 이용한 처음 질문의 답변: 위 예시에서는 HAVING절에서 집계함수를 사용하지 않고 단순히 나이>=20의 비교를 수행했기 때문에 WHERE절에서도 처리가 가능하다.
그래도 궁금한 점은 HAVING절에서 집계함수가 없이 WHERE절로 처리 가능한 경우에 어떻게 처리하는 방식이 효율적인지 추가적인 질문이 필요해보인다.
ㄴ해당 내용 질의메일 전송완료
Q2. 지금 까지 앞에 EXISTS예제에서 다 사용한 상호연관질의문에 대한 개념이해 부족..
상호연관질의문을 사용해서 웬만한 문제는 다 풀 수 있는게 아닌지 내일 다시 분석.. 오늘은 여기까지.