ASAC-SK플래닛 T아카데미 데이터 엔지니어

25.10.21 9일차 [ SQL 기초 개념 강의_(DQL 문법 SELECT, 서브쿼리, order by, distinct ~ from, limit, group by, having, rollup, join, union)]

Datadesigner 2025. 10. 22. 01:18

잘못 들어갔는데 뭔가 멋있어서 그냥 앞에 둔다

 

 

오늘은 어제에 이어서 DQL에 관련된 다른 많은 문법들을 배웠다. 문법이라고 표현하는게 맞나?

 

수업 내용
  • SELECT ~ FROM
  • SELECT ~ FROM ~ WHERE ~
    • SELECT FROM WHERE BETWEEN
    • IN
  • 서브쿼리
    • ANY | SOME
    • ALL
  • ORDER BY
  • SELECT ~ DISTINCT ~ FROM
  • LIMIT
  • GROUP BY ->  집계
  • HAVING
  • ROLLUP
  • JOIN
  • UNION , UNION ALL

  • SELECT ~ FROM
    • 특정 테이블로부터 데이터 추출(획득)
    • 가장 기본 조회 쿼리
1. SELECT * FROM CITY;

 

2. SELECT `NAME FROM CITY ( NAME 파트만 추출된다, NAME을 감싼것은 따옴표가 아닌 백팁` 인것을 절대 잊으면 안된다 )

 

3.SELECT `NAME` , POPULATION FROM CITY;

 

4. AS로 별칭을 부여하였을때 결과셋의 이름이 변한다.

 

  • SELECT ~ FROM ~ WHERE ~
    • 특정 조건에 해당되는 조회 결과만 추출 (획득, 가져옴){
    • 조건이 없다면 전체데이터 -> 데이터 양에 따라 렉이 걸릴수 있음 (자제)
    • 조건 => 연산자
      • - 조건 연산자 ( =, <, >, <=, >=, <> , != ) -> <> 과 != 는 같은 뜻임
      • - 관계 연산자 ( NOT, AND, OR)
      • - 연산자 조합으로 구성됨
- 요구사항
city 테이블에서 인구수 5000000 이상 되는 도시 데이터 추출
컬럼 정보 전부 획득

select * 로 모든 데이터를 결과값으로 추출, from city로 시티 테이블에서 추출, where city.population >= 5000000으로 city 테이블에서 인구수 5000000 이상인 데이터만 추출.

 

같은 조건에서 and 연산자를 사용하여 두가지 조건 입력


count() 함수?를 이용하여 도시의 개수 추출

 

!= 연산자 사용, 1780000이 아닌 모든 도시 수 추출



or 연산자 사용, countrycode 컬럼으로 국가코드로 각 조건에 맞는 데이터 추출 문법은 (데이터).(컬럼) 국가코드엔 반드시 ''문자열 표기

 

이렇게도 사용 가능함.




-- 조건식의 배치에 따라 결과셋이 완성되는 시간(자원)이-- 상이함
-- 최적화(표현, 수행시간, 리소스사용량등 고려)-- 조건식 구성
순서를 바꿔주는것이 수행시간에는 더욱 도움이 된다.

 

 

  • select ~ from ~ where ~ between
    • between 
      • 조건에 사용되는 컬럼의 데이터가 수치형(연속형) 에 해당되는 경우
      • between a and b 조합
      • a <= x <= b
between을 사용하여 더욱 간결하게 식을 구성하였다, 근데 난 이게 더 헷갈린다

 

  • in
    • 컬럼 데이터가 범주형 데이터인 경우 적합하다
      • 특정 컬럼의 데이터의 종류를 셀 수 있다.
      • 범위 x , 구분용도
    • 나열한 데이터중에 포함되면(in) 추출 대상이 됨
in을 모르면 이렇게 해야된다.
in을 사용하면 더욱 깔끔하게 바꿀수 있다.

 

별칭, in, count()를 이용한 문제
and 연산자를 사용한 다양한 데이터 추출 바리에이션
  • 서브쿼리 (sub query)
    • 쿼리문 내에 쿼리문 존재
    • 주의사항
      • 서브 쿼리문의 결과셋이 2개 이상이 나오는 경우 오류 발생함 -> 해결방안은 any | some
    • 위치
      • 조건의 값 (아래 예시)
        • where ~
        • having ~
    • 필요한 곳이면 모두 사용가능
      • from 서브쿼리(결과셋은 n개 ok)
        • join 진행시 체크 예정
서브쿼리 1단계 : 파리의 도시명을 사용해서 국가코드 획득

 

2단계 : 얻어낸 국가코드로 모든 도시 정보 추출


이를 서브쿼리로 수행하면

'fra'값에 1단계에서 국가코드를 얻어낸 쿼리를 괄호에 감싸 넣어서 서브쿼리를 만든것이다. 서브쿼리가 메인쿼리보다 먼저 작동한다

서브쿼리 오류상황

위 쿼리를 실행하면 위와같은 오류창이 떠오른다.

그 이유는 결과셋이 2개 이상이기 때문인데 

서브쿼리에 있는 결과셋이 2개 이상이기 때문이다. 위 사진에서는 6개이다.

위 문제를 해결하는 방법은!

 

 

1. any | some ( 한 개의 조건이라도 만족 )

 

한 가지 조건만 만족하면 어떤것이든 상관없다는거다. > any를 사용해서 city.district가 'new york'인 도시중 어느 하나보다 더 인구수가 많은 도시는 모두 출력하라는 의미이다.

 

같은 위치에 some을 사용해도 같은 결과를 도출한다.



in 과 같은 효과를 내려면 = 를 사용하면 뉴욕 도시와 똑같은 인구수를 가진 결과를 받는다.
같은 명령어로 population을 countrycode로 바꾸면 국가코드가 usa인 모든 도시가 추출된다.

 

2. all ( 모두 만족)

any와 다른 점은 any는 한 개의 도시보다도 인구값이 크면 모두 출력하였고 all은 뉴욕의 모든 도시보다도 인구값이 큰 도시만 출력하였다.

 

  • order by
    • 조회 결과(결과셋)을 특정 조건에 맞게 정렬 -> 파이썬에선 sort()
    • 기본값
      • ASC(오름차순)
      • 생략 가능
    • 기타값
      • DESC (내림차순)
    • 형식
      • ORDER BY 컬렴명 | 조건식 정렬키워드 [ , , , , ,  [ 반복 ] ]
기본 적용
ASC는 생략 가능하다.
DESC를 사용하면 내림차순으로 정렬 가능하다.
두 가지 기준으로 정렬도 가능하다, 하지만 이 방식은 잘 표가 나지 않는다
정렬할 순서를 수정하여 AFG COUNTRYCODE가 인구수로 정렬된 것을 확인할 수 있다.
모든 데이터를 추출 후 정렬하기 때문에 ORDER BY는 대체로 조건구문 이후 마지막에 위치한다.

 

  • select ~ distinct ~ from
    • 중복 제거
    • 중복된 데이터가 존재한다면 1개만 출력함
    • select express 에서 사용
    • 뒤에 나오는 컬럼과 조합하여 사용함
  • 문법
    • select distinct 컬럼
city에는 약 4000개의 row 값이 있지만 중복을 제거하여 232개만 추출된다.

 

그냥 추출하면 이렇게 됨

 

  • limit
    • 결과셋의 개수(혹은 범위)를 제한
      • 형식
        • limit n
        • 상위부터 n개까지만 출력
          • limit n , m
          • 게시판의 페이징 처리시 사용
1. 테이블명이 길어서 별칭으로 뺐음 2. 면적과 이름으로 결과셋 세팅 3. 정렬 여기서 상위 top 10만 추출하려면?
limit 10 으로 상위 10개만 추출하였다.
limit n , m 은 이런식으로 작동한다


총 데이터가 239개이니 한 페이지당 10개로 잡고 한 페이지씩 넘기다보면 마지막 페이지는 9개가 될까?

그렇다

 

  • group by (집계)
    • 특정 컬럼을 그룹화하여 집계
    • 특정 컬럼의 같은 값을 가진 (조건에 맞게 그룹화된) 데이터를 모아서, 집계 수행
    • 모아진 데이터는 별칭을 사용하여 관리
    • 그룹의 대표값을 설정함으로, 세부 정보를 손실됨
      • 집계 후 select_express 에서 사용할 수 있는 대상
        • **집계의 대상이 된 컬럼**
        • **집계함수를 사용한 형태**
    • 집계 함수들과 같이 사용(활용)
      • AVG()
      • MIN()
      • MAX()
      • COUNT()
      • COUNT(DISTINCT~)
      • STDEV()
      • VARIANCE()
각 국가코드를 그룹화 한 후, 같은 국가코드를 가진 도시의 인구 최소값을 별칭으로 부여하여 오름차순으로 정렬 후 탑10만 출력

 

비슷한 조건에 다른 형식으로 조금씩만 변형된 문제

끝이 보인다...

 

  • HAVING
    • 1차 조건에 대한 결과셋 에 대한 2차 조건
      • WHERE : 최초 (1차) 결과셋을 구성하는 내용 조건
      • HAVING : 최초 혹은 집계(통상 2차) 이후 내용에 대한 조건
        • WHERE ~ HAVING ~
        • WHERE ~ GROUP BY ~ HAVING
1차 조건
2차 조건 : 900만명 이상만 출력 = HAVING MAX_POPU >= 9000000
이거 하는데 거의 1시간은 걸린듯, 서브쿼리는 엄두도 못 냈다

 

  • rollup
    • 중간 집계
    • group by ~ with rollup
1. 같은 국가코드를 가진 데이터의 도시의 인구수를 합산. 까지는 지금까지 배운 내용으로 충분히 할 수 있다.
2. with roll up은 결과를 보여주기 전 중간집계를 보여주는 기능으로 각 도시별 결과셋을 한개 더 부여해서 도시별 인구수 또한 표현해주고, 합산까지 마치는 내용을 준다.

 

  • join
    • 데이터베이스내에 다른 테이블의 레코드와 조인하여, 새로운 결과셋을 형성한다.
    • 문법 
    • SELECT *
      FROM 테이블 1 as a
      JOIN 테이블 2 as b
      ON a.컬럼 = b.컬럼
      ;
    • 테이블이 다르기 때문에 헷갈리지 않으려면 use 데이터베이스; 를 사용하거나 별칭으로 꼭 테이블을 지정해줘야한다.

각 join의 도식화

city = 4079
country = 239


각 데이터값은 4079개, 239개이다.
가장 기본적인 조인
2개 테이블에 공통으로 존재하는 컬럼 (지금의 경우에는 국가코드다) 
공통 컬럼을 중심으로 데이터를 연결한다.

4079 = city테이블의 총 데이터 수 , 모든 컬럼 수( city테이블의 컬럼 + country 테이블의 컬럼 수)


요구사항
-- 필요한 데이터만 추출
-- 도시명, 국가코드, district, 인구수, 면적만 추출한다
-- 컬럼명도 위에 언급한대로 구성

1. 결과셋에 각각 테이블 컬럼을 지정해주며 별칭으로 표기.
2. from 과 join 에 테이블 별칭 지정
3. join
4. city 테이블에는 없는 surfacearea컬럼이 추가된 채로 결과셋이 구성된것을 확인할 수 있다.

3개의 테이블을 합친 모습, 하지만 데이터가 너무 많다


left join
왼쪽 테이블의 데이터 수 보장 -> 4079행


right join
오른쪽의 데이터는 보장(고정) 조인 이건 아직 사실 잘 모르겠다

 

  • union, union all
    • 두 개 이상 결과 집합을 합친다
    • 단, 컬럼수, 이름이 동일해야 함
      • 차이
        • union : 중복 제거 O 원본에 비해 데이터수 줄어들 수있음
        • union all : 중복제거 X 모두 합쳐짐
인구수 80만 이상 - 8개
인구수 9000000 이상 = 1개

인구수가 80만 이상인 한국의 도시는 1개
인구수가 900만 이상인 한국의 도시는 8개 이다, 이중 서울 하나만 겹친다, 이때 
union을 사용한다면

중복되는 서울 데이터를 1개 삭제하고 총 8개가 추출되는걸 볼 수 있다.
이때 union all을 사용한다면

중복되는 서울이 삭제되지 않고 1행 9행에 모두 존재하는것을 볼 수 있다.

 


오늘 진짜 진짜 머리가 터질뻔했다.

 

파이썬은 5일동안 해서 아주 조금 적응이 되려 했는데 sql로 넘어가니까 어김없이 작은 실수들이 계속 생긴다.

 

언어 파트에서 제일 어려운 점은 아주 작은 실수면 값이 다르게 나오기도 하지만 아예 값이 안 나오기도 한다.

 

 백팁이랑 따옴표 하나 차이를 못봐서 10분을 날리고 막 그런다 ㅋㅋ

 

수업시간에 강사님이 작성해 준 코드를 따라 쳤는데 도대체 왜 내건 작동이 안되지?

 

이유를 찾으려고 고민하고 생각하고 조금 정신을 다른데에 두면 진도가 확확 나간다.

 

배워야 할 정보는 넘쳐나는데 시간은 한정되어있으니 어쩔수 없지만 작은 실수에 진도를 놓쳐버리니 너무 화가 났다.

 

그래서 오늘은 4시부터 있는 리뷰시간에 처음부터 다시 입력해보고 집에 와서 다시 오늘 배운 내용을 처음부터 끝까지 다 다시 해봤다. 지금 새벽 2시반이다

 

작은거 하나라도 놓치면 나중에 어떻게 돌아올지 알 수가 없고 간단한 수업도 못 따라가는 내 자신이 너무 화가나서 도저히 안 할수가 없었다. 

 

실무에서는 이 기능들은 기본으로 당연히 머리속에서 바로바로 떠오르고 일을 할 때에는 이 기능들을 사용해서 다양한 퍼포먼스를 내야 할 텐데 

 

그러기 위해서 기초는 당연히 기본이다,  툴이라는것은 말 그대로 도구다

 

그 도구를 사용해서 어떤걸 만드느냐가 실무이고 실력인데, 지금은 그 툴마저도 제대로 못 쓰고 있다.

 

스케치업, 캐드를 공부하고 진짜 잘 쓸줄 몰랐던 과거 학부시절이 생각났다, 회사에서는 진짜 손이 날아다녔는데 생각해보면 학부때에는 기능 하나하나 네이버에 검색해가며 익히고 그렇게 익힌 기능들을 체화시키고 사용하며 프로젝트를 만들었었지.

 

그걸 4년동안 했으니 당연히 체화되었을것이고 지금은 그 과정을 다른 기술에서 처음부터 하고 있다고 생각한다.

 

배우면 배울수록 모든 학문은 일맥상통한다는 말도 생각나고 그냥 그렇다.

 

지기 싫다 더 해야지