오늘은 SELECT 구문을 학습하였습니다.

Today I Learned
SELECT
- 산술연산을 통한 조회
- 숫자연산 +
- select title, hit+1 as hit from notice;
- 컬럼명이 hit+1이 되므로 as를 통해 이름 지정
- 만일 title에 +1을 한다면? 에러가 남(수치 부적합)
- 문자열 연산 ||
- select '3' || 10 from dual; -> 결과 310
- select '3' + 10 from dual; -> 결과 13
- 비교연산자
- =, !=, ^=, <>, >, <, >=, <=, IS NULL, IS NOT NULL
- !=, ^=, <>는 동일한 연산자
- 비교 연산자는 where절에 사용한다.
- NOT, AND, OR, BETWEEN, IN
- 연속된 값
- select * from notice where hit=0 or hit=1 or hit=2;
- select * from notice where 0 <= hit and hit <= 2;
- select * from notice where hit between 0 and 2;
- 연속되지 않는 값
- select 8 from notice where hit in (0,2,7)
- in <-> not in : 여집합 관계
- 패턴으로 조회
- like, %, _
- select * from member where name like '박%'
- % : 글자수 한정하지 않음
- _ : 글자수 한정
- 조금 더 세밀한 패턴 조회 방법
- 정규표현식
- REGEXP_LIKE(컬럼명, 정규표현식) 함수 사용
- 제한적인 부분(특정 부분) 조회
- 행을 제한하기
- ROWNUM
- select rownum, member.* from member where rownum between 1 and 5;
- rownum을 생성하여 순서대로 정렬함
- 실행순서 이해하기
- from > where > select
- where절을 수행하면서 rownum 생성됨
- rownum은 무조건 1부터 시작함
- select rownum, member.* from member where rownum between 6 and 10; (x)
- 1부터 생성되어 where 절의 조건을 검사해서 조건을 만족해야 그 다음 번호가 생성된다.
- 그렇다면 rownum between 6 and 10을 하고 싶다면?
- rownum의 모든값을 담는 select문을 서브쿼리로 만들고 그 결과테이블에서 범위를 지정하여 페이징 가능
- select from (select rownum as num,member. from member) where num between 6 and 10;
- 중복제거
- DISTINCT
- 동일한 값들을 여러개 갖고있다면, 하나만 출력
- 내장함수
- length()
- substr()
- 등등 다양한 내장함수 존재.
SELECT문의 구절
- 작성 순서 : select > from > where > group by > having > order by
- 실행 순서 : from > where > group by > having > select > order by
- 집계하기
- 집계함수 : SUM, MIN, MAX, COUNT, AVG
- count(속성) : 해당 컬럼에서 값의 갯수. null값은 세지 않는다.
- 모든 집계함수는 속성에 따라서 결과가 달라질 수 있음을 유의한다.
- where 절에는 집계함수 사용 불가(> having 절에서 사용한다)
- 그룹별 집계
- group by : ~별
- 작성자별 게시글 수 조회하기
- select writer_id, count(id) from notice group by writer_id;
- HAVING
- where절과 같은 기능이지만, 집계한 뒤에 집계함수를 활용하여 조건을 달아주고 싶을때 사용.
- 작성자별 게시글 수를 조회, 게시글 수가 2개 이상인 것만 조회
- select writer_id, count(id) from notice group by writer_id having count(id) >=2;
- ORDER BY
- ASC : 오름차순(기본값)
- DESC : 내림차순
- 작성자별 게시글 수를 조회, 게시글 수가 2개 이상인 것을 게시글 수로 내림차순(오름차순) 정렬
- select writer_id, count(id) from notice group by writer_id having count(id)>=2 order by count(id) desc(asc);
서브쿼리
- 사용처 : 구절의 순서를 바꿔야 하는 경우.
- 최신 등록순으로 정렬한 결과에서 상위 열명을 원하는 경우라면?
- 먼저 최신 등록순으로 정렬하는 결과가 필요함.
- 하지만 정렬은 order by절로 수행하는데, 이는 실행순서가 가장 마지막에 이루어짐.
- 이런 문제를 해결 하기 위해 서브 쿼리를 사용
- 정답
- select rownum, notice.* from (select * all from notice order by regdate desc) where rownum between 1 and 10;
- 그렇다면, 그 다음페이지인 11번부터 20번까지를 얻어오고 싶다면?
- rownum은 1부터만 번호를 부여할 수 있음.
- 즉 , 이말은 rownum between 11 and 20 이 불가능함(현상황에서)
- 해결
- select num, notice.* from (select rownum num,M.* from (select * from notice order by regdate desc) N) M where num between 11 and 20;
- 해설 : 먼저, 등록일자 순으로 정렬 = M >> 그 정렬된 M을 가지고 순서 번호(rownum)를 매겨주고, 매겨진 번호들 중 select 할 번호만 뽑아주면 됨
- 즉, 서브쿼리는 먼저 실행해서 얻어야 할 값 또는 값들의 집합, 레코드의 집합이 필요할 때 사용한다.
- 만약, 비교하고자 하는 값이 여러개 일 경우엔?
- ALL, ANY를 사용하자.
- ALL(SUBQUERY) : 서브쿼리의 결과값들 모든 것보다 ~~ 하다 할때.
- ANY(SUBQUERY) : 결과값들 중 어떤 하나보다 ~하면 된다.
번외 : 연습문제
조금 더 많은 쿼리 문제를 풀어보고 연습할 필요가 있겠습니다.