Étude
article thumbnail
Published 2023. 11. 27. 00:14
[SQL] 테이블 조회 Programme/SQL

SELECT / ALIAS

SELECT 문은 SQL에서 가장 기본이 되는 문장 중 하나로, 데이터베이스에서 원하는 정보를 가져오는 데 사용된다.

SELECT의 기능은 다음과 같다.

  1. 특정 열 선택: SELECT 문을 사용하여 원하는 열(칼럼)만 선택할 수 있다. 이를 통해 필요한 정보만 가져올 수 있다.
  2. 모든 열 선택: 별표(*)를 사용하여 모든 열을 선택할 수 있다. 이를 통해 테이블의 전체 데이터를 가져올 수 있다.
  3. 조건에 맞는 행 선택: WHERE 절을 사용하여 원하는 조건에 맞는 데이터만 선택할 수 있다. 이를 통해 특정 조건에 따라 검색 결과를 필터링할 수 있다.
  4. 정렬: ORDER BY 절을 사용하여 선택한 열을 기준으로 결과를 정렬할 수 있다. 오름차순(ASC) 혹은 내림차순(DESC)으로 정렬할 수 있습니다.
  5. 중복 제거: SELECT DISTINCT 문을 사용하여 중복된 값을 제거할 수 있다.
  6. 연산 및 함수: SELECT 문에서는 다양한 연산과 함수를 사용할 수 있다. 예를 들어, 숫자 열의 합계(sum), 평균(avg), 최대값(max), 최소값(min) 등을 계산할 수 있다.

 

 

 

해당 데이터에 대해 작업을 수행한다.

create table melon_chart (
    ranking     	int,
    song    	varchar(50),
    singer		varchar(20),
    album		varchar(50),
    like_no	int
);

insert into melon_chart values (1, 'Super Shy', 'NewJeans', 'NewJeans 2nd EP Get Up', 115766);
insert into melon_chart values (2, 'Seven (feat. Latto) - Clean Ver.', '정국', 'Seven (feat. Latto) - Clean Ver.', 124699);
insert into melon_chart values (3, 'ETA', 'NewJeans', 'NewJeans 2nd EP Get Up', 60239);
insert into melon_chart values (4, '퀸카 (Queencard)', '(여자)아이들', 'I feel', 125309);
insert into melon_chart values (5, 'I AM', 'IVE (아이브)', 'Ive IVE', 188847);
insert into melon_chart values (6, '헤어지자 말해요', '박재정', '1집 Alone', 96577);
insert into melon_chart values (7, '이브, 프시케 그리고 푸른 수염의 아내', 'Le SSERAFIM (르세라핌)', 'UNFORGIVEN', 96863);
insert into melon_chart values (8, 'Spicy', 'aespa', 'MY WORLD - The 3rd Mini Album', 115388);
insert into melon_chart values (9, 'Steal The Show (From 엘리멘탈)', 'Lauv', 'Steal The Show (From 엘리멘탈)', 108665);
insert into melon_chart values (10, 'New Jeans', 'NewJeans', 'NewJeans 2nd EP Get Up', 57308);

 

 

중복된 값이 있을때, DISTINCT로 중복이 제거된 값을 확인할 수 있다.

SELECT * FROM melon_chart;
SELECT DISTINCT singer FROM melon_chart ;
SELECT count(DISTINCT singer) FROM melon_chart

*은 데이터를 전부 가져오라는 것을 의미한다. 저 상태는 깡통차와 같다. 아무런 옵션이 없기 때문이다.

 

DISTINCT를 통해서 중복이 제거된 고유값들만 볼 수가 있다. 또한 count 옵션을 걸어 중복을 고려한 총 데이터의 집계를 확인 할 수 있다.

이때, 아래와 같이 AS로 header의 출력에 옵션을 걸어 Header명을 간결하게 출력되도록 할 수 있다.

 

만약에 한글이나 특수기호를 Header명에 포함할 경우 따옴표로 정의한다.

SELECT count(DISTINCT singer) as '가수(명)' FROM melon_chart ;

 

 

 

 

  • 다양한 경우들

singer가 NewJeans일때 ranking과 song 컬럼을 불러온다

SELECT ranking, song from melon_chart where singer = 'NewJeans';

singer가 NewJeans이고 ranking이 6위 미만인 값을 다 불러온다.

SELECT * from melon_chart where singer = "NewJeans" and ranking < 6;

singer가 정국이거나 박재정일 경우의 값을 모두 불러온다.

SELECT * FROM melon_chart where singer = '정국' or singer = '박재정';

데이터양이 방대할 경우, LIMIT으로 조회하고자 하는 데이터의 숫자를 제한해줄 수 있다. 이때는 LIMIT 뒤에 숫자에 따라 출력양이 정해지게 된다. 조회되는 순서는 DB가 저장된 순서이다. python의 head와 같은 용도로 사용한다.

SELECT * FROM melon_chart LIMIT 3;

 

 

WHERE(+ IN, LIKE, BETWEEN)

WHERE절을 통해 특정 조건에 부합하는 데이터들만 조회할 수 있다.

 

 

  • IN

어떠한 컬럼에 특정값이 포함된 경우를 조회하고 싶을때 사용한다.

‘이 안에 있다면 보여주세요!’라고 생각할 수 있다. 반대로 NOT IT일 경우 ‘이 안에 있다면 제외해 주세요!’로 생각할 수 있다.

SELECT * FROM melon_chart WHERE song in ('I AM', 'Super Shy', 'Spicy');
SELECT * FROM melon_chart WHERE song = 'I AM' or song = 'Super Shy' or song = 'Spicy';

 

song의 값이 i am 또는 super shy 또는 spicy 일 경우 출력한다. 두 쿼리는 같은 의미이다.

 

 

만약 or 과 and을 혼용하고 싶을 경우 아래와 같이 확실하게 괄호를 넣어 사용하도록 하자.

아래 쿼리에 괄호가 없을 경우 마지막 부분의 ‘song = 'Spicy' and singer = 'NewJeans'에 괄호가 되어 있는거로 인식한다.

SELECT * FROM melon_chart WHERE (song = 'I AM' or song = 'Super Shy' or song = 'Spicy') and singer = 'NewJeans';



  • LIKE

부분적으로 일치하는 칼럼을 찾을때 사용한다.

_ : 글자숫자를 정해줌(EX 컬럼명 LIKE '홍_동')

% : 글자숫자를 정해주지않음(EX 컬럼명 LIKE '홍%')

SELECT * FROM melon_chart WHERE song like '이브%'; #이브로 시작하는 노래 
SELECT * FROM melon_chart WHERE song like '%말해요';
SELECT * FROM melon_chart WHERE song like '%S%'; #S가 들어간 모든 조건 
SELECT * FROM melon_chart WHERE singer like '정_'; #%가 어떤 문자열을 의미한다면 _는 문자 하나 
SELECT * FROM melon_chart WHERE song like '_카%';

 

 

만약 %나 _를 포함하는 값을 조회하고 싶다면? ESCAPE문을 활용하자!

찾고싶은 기호 앞에 ESCAPE 문자를 정의하여 사용한다. ESCAPE문자에는 \, #등 모든 문자가 가능하지만, 실제로 검색시에 잘 쓰지 않는 문자를 사용하는것이 좋다.

SELECT * FROM test WHERE col like '%#%%' ESCAPE '#';   # %기호가 포함된 데이터 출력 
SELECT * FROM test WHERE col like '%$%%' ESCAPE '$';  #동일하게 작용
  • BETWEEN

말 그대로 특정 값 사이에 있는 데이터를 조회한다. 여기서 주의할 점은 경계값을 포함한다는 것. 즉 이상과 이하로 조회된다.

SELECT * FROM melon_chart WHERE like_no BETWEEN 100000 AND 150000;

 

 

ORDER BY(+ LIMIT)

SELECT 문을 사용할 때 출력되는 결과물은 테이블에 입력된 순서대로 출력되는 것이 기본이다. 하지만 우리는 가끔은 내림차순으로 혹은 오름차순으로 정렬된 데이터들이 필요할 때가 있다. 이때 사용하는 것이 ORDER BY 절.

기본값은 ASC(오름차순)이다.

SELECT * FROM melon_chart ORDER BY ranking; 
SELECT * FROM melon_chart ORDER BY ranking desc; #내림차순
SELECT song,singer FROM melon_chart ORDER BY ranking desc; #정렬된 두 컬럼 출력 

SELECT * FROM melon_chart WHERE singer not in ('정국','박재정') ORDER BY song; #정국과 박재정이 아닌 값들에 대해 정렬

다음과 같이 ORDER BY 절에 두 컬럼이 적용됐다면, 첫번째 컬럼에 우선 정렬되고 중복된 값들에 대해서만 다시 정렬한다.

SELECT * FROM melon_chart ORDER BY singer, like_no desc;

 

  • LIMIT 정렬후 Return할 데이터 수를 정한다. 만약 두번째 쿼리문과 같이 되어있다면 4번째 데이터 부터 5개의 row를 return하라는 것을 의미한다. 페이징할때 많이 쓴다고 한다.
SELECT * FROM melon_chart ORDER BY like_no desc limit 3;
SELECT * FROM melon_chart ORDER BY like_no desc limit 3,5; #4번째 데이터 부터 5개 row를 불러와라. 페이징할때 많이 씀

 

 

Aggregate Function

집계 함수는 여러 행으로부터 하나의 결괏값을 반환하는 함수이다. SELECT 구문에서만 사용되며, 컬럼끼리의 연산을 수행한다.

COUNT, SUM, MIN, MAX, AVG 등이 쓰이며 Python이나 엑셀 등과 같이 기능한다.

SELECT COUNT(*) from melon_chart; #데이터의 건수 return/  *대신 숫자여도 똑같이 기능 
#컬럼명이 들어갔을땐 null값 제외 건수 return 

SELECT SUM(like_no), SUM(ranking) FROM melon_chart;  #각각 총합 return

SELECT AVG(like_no) FROM melon_chart;  #null 값은 아예 없는 데이터로 취급. 0이 아님. 

좋아요 수가 100000개 초과인 컬럼이 몇개 있는지를 물어보는 쿼리문이다.

#응용
SELECT COUNT(*) from melon_chart WHERE like_no > 100000; 

GROUP BY

특정 칼럼을 기준으로 집계 함수를 사용하여 건수(COUNT), 합계(SUM), 평균(AVG) 등 집계 데이터를 추출할 때 사용한다. GROUP BY 절에서 기준 칼럼을 여러 개 지정할 수 있으며, HAVING 절을 함께 사용하면 집계 함수를 사용하여 WHERE 절의 조건절처럼 조건을 부여할 수 있다. GROUP BY 절은 중복제거를 할 때도 사용 가능하다. 편하게 보기 위해 ORDER BY를 사용하여 쿼리문을 작성하는 것이 좋다.

아래의 테이블을 사용한다.

create table animal_info (
    animal    varchar(20),
    type	     varchar(20),
    name     varchar(30),
    age       int
);

insert into animal_info values ('강아지', '포매라이언', '망고', 3);
insert into animal_info values ('고양이', '먼치킨', '두부', 5);
insert into animal_info values ('고양이', '샴', '망고', 5);
insert into animal_info values ('고양이', '페르시안', '제니', 1);
insert into animal_info values ('강아지', '치와와', '칫치', 11);
insert into animal_info values ('강아지', '푸들', '꼼데', 7);
insert into animal_info values ('강아지', '포매라이언', '몽이', 1);
insert into animal_info values ('강아지', '치와와', '초코', 5);
insert into animal_info values ('고양이', '먼치킨', '살구', 9);
insert into animal_info values ('고양이', '페르시안', '캔디', 13);
insert into animal_info values ('강아지', '푸들', '가르송', 6);
insert into animal_info values ('강아지', '진돗개', '백구', 10);
insert into animal_info values ('강아지', '웰시코기', '까미', 12);
insert into animal_info values ('고양이', '러시안 블루', '구름', 1);
insert into animal_info values ('고양이', '먼치킨', '까미', 4);
insert into animal_info values ('고양이', '샴', '도리', 8);
insert into animal_info values ('고양이', '러시안 블루', '라떼', 4);
insert into animal_info values ('고양이', '먼치킨', '녹두', 2);
insert into animal_info values ('강아지', '포매라이언', '별이', 8);
insert into animal_info values ('고양이', '페르시안', '나나', 5);

다음과 같이 사용할 경우 에러가 난다**. G**ROUP BY 절에서는 집계 함수를 제외한 다른 열을 선택할 수 없기 때문이다. 따라서 두번째 쿼리문처럼 기준 컬럼까지 넣어서 사용해준다.

SELECT * FROM animal_info GROUP BY animal; #에러남. 

SELECT animal FROM animal_info GROUP BY animal; #
 
SELECT animal, max(age)  FROM animal_info GROUP BY animal; #group별 누가 나이가 가장 많은지 

 #group별 누가 나이가 가장 많은지 + name까지 알고 싶다고 아래처럼 하면 error =>  GROUP BY 절에서는 집계 함수를 제외한 다른 열을 선택할 수 없기 때문
SELECT animal, max(age),name  FROM animal_info GROUP BY animal;

#age별 분포 확인
SELECT age, COUNT(*) FROM animal_info GROUP BY age ORDER BY age;

#동물별, 종별 분류 
SELECT animal, type, COUNT(*) FROM animal_info GROUP BY animal, type ORDER BY animal; 

#강아지만 보고 싶다면? 
SELECT animal, type, COUNT(*) FROM animal_info WHERE animal ='강아지' GROUP BY animal, type;  

SELECT animal, type, MIN(age), MAX(age) FROM animal_info GROUP BY animal, type ORDER BY animal;

    

월별 매출, 회원 연령대별 가입현황 관련해서 많이 쓰이니 숙지하는게 신상에 좋을 것이다.

 

 

Having

 

HAVING 절은 그룹화한 결과에 조건을 걸고자 할 때 사용한다. HAVING 절은 집계함수를 이용한 조건비교를 할 때 사용한다. WHERE 절에서는 집계함수를 이용할 수 없다는 점이 차이점이다

WHERE은 집계함수를 이용할 수 없기 때문에 아래 쿼리에선 에러가 발생한다.

SELECT animal, type, count(*) FROM animal_info WHERE COUNT(*) > 2 GROUP BY animal, type; #오류

다음과 같이 WHERE절이 아닌 HAVING을 이용해서 집계함수를 사용하여 조건을 걸어 줄 수 있다.

SELECT animal, type, count(*) FROM animal_info GROUP BY animal, type HAVING COUNT(*) > 2;

정렬을 시킬경우 쿼리 맨 마지막에 ORDER BY절을 추가해주면 된다.

 

SELECT animal, type, count(*) FROM animal_info GROUP BY animal, type HAVING COUNT(*) > 2 ORDER BY COUNT(*) DESC  ;

 

 

 

 

그러면 ‘고양이’의 경우만 보고싶을땐?

이럴 경우에 WHERE을 사용한다. 다음을 실행시키면 고양이의 경우만 조회할 수 있다.

SELECT animal, type, count(*) 
FROM animal_info 
WHERE animal ='고양이'
GROUP BY animal, type 
HAVING COUNT(*) > 2 
ORDER BY COUNT(*) DESC;

그런데 HAVING에도 조건을 시키면? 같은결과가 나오지 않을까?

맞다. 같은결과가 나온다. 하지만 이렇게 쓰면 안된다!

SELECT animal, type, count(*) 
FROM animal_info 
GROUP BY animal, type 
HAVING COUNT(*) > 2 AND animal = '고양이'
ORDER BY COUNT(*) DESC;

왜 이렇게 안되는지 이해를 하기 위해선 SQL 쿼리의 프로세스를 이해해야 한다.

SQL 프로세스

1. 데이터 가져오기 (From, Join)

2. 조건문 행 필터링 (Where)

3. 그룹핑 (Group by)

4. 그룹핑 결과 필터링 (Having)

5. 결과 리턴 (Select)

6. 결과 정렬 (Order by & Limit / Offset)

 

SQL 쿼리는 이렇게 프로세스가 구성된다. 만약 방금 쿼리에서 animal =’고양이’조건을 HAVING절에다가 걸었으면 어떻게 될까? 조

조건문 행 필터링 없이 GROUP BY 로 grouping된다. 만약 animal 조건에서 강아지,토끼,이구아나 등등 여러가지 동물들이 있었다면? 불필요하게 프로세스 과부화를 시키는 과정이 될것이다. 지금이야 데이터가 몇개 안되니 상관없어 보일 수도 있지만, 대용량 데이터를 다루면서 이런 식으로 하면 안될 것이다.

 

profile

Étude

@프랑스어전공

https://blog.naver.com/captprice