TIL(Web)-2020.12.10(SQL SELECT)

BYEONGJUN KIM(JUN)·2020년 12월 10일
0

TIL(Web)

목록 보기
7/45

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

Today I Learned

  • DML SELECT

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 : ~별
      • ex) 회원별 구매액 조회 가능
    • 작성자별 게시글 수 조회하기
      • 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) : 결과값들 중 어떤 하나보다 ~하면 된다.

번외 : 연습문제

  • 게시글을 하나도 작성하지 않은 회원의 이름과 연락처를 출력하라
  • 정답
    select name, phone from member where name not in (select writer_id from notice group by writer_id having count(id) != 0);

조금 더 많은 쿼리 문제를 풀어보고 연습할 필요가 있겠습니다.
profile
Web Backend 개발자

0개의 댓글

관련 채용 정보