5 min read

SQL 첫걸음 5장

20강: 행 개수 구하기 - Count

1. Count로 행 개수 구하기

일반적인 함수는 인수로 하나의 값을 지정하는 데 비해 집계함수는 인수로 집합을 지정한다. 따라서 집합함수라고 부른다.

count(집합)
select count(*) from sample; -> 샘플의 행을 다 count 해준다.

집합으로부터 하나의 값을 계산해줌.

select count(*) from sample where col=' ';

이렇게 하면 where 먼저 실행 후 select 구문이 실행된다. count 함수만 인수 *를 지정할 수 있다.

2. 집계함수와 Null 값

Null값은 제외하고 처리하게 된다.

3. Distinct로 중복 제거

중복된 값이 있는지 여부에 따라 문제가 될 때가 있다. 이럴 때 사용하는 함수가 Distinct다.

select distinct col from sample;

이렇게 지정해주면 중복된 데이터를 제외한 결과를 클라이언트로 반환한다. *로 지정하면 중복 여부 상관없이 모든 행을 반환한다.

4. 집계함수에서 Distinct

null 값을 제외하고 중복하지 않은 데이터를 구하는 건 불가능하다. 그러나 집계함수의 인수로 Distinct을 사용한 수식을 지정하면 가능하다. distinct로 중복을 제거하고 count로 개수를 구할 수 있다.

select count(All name), count(distinct name) from sample;

이렇게 해주면 가능하다. all은 생략 가능하다.

21강: Count 이외의 집계함수

1. Sum으로 합계 구하기 집계함수는 count말고 sum 집계함수를 사용해 집합의 합계를 구할 수 있다. col 값의 총 합을 구해준다.

select sum(col) from sample;

따라서 sum은 수치형에만 사용할 수 있다. Null이 있을 경우 무시하고 합을 구해준다.

2. AVG로 평균내기

sum과 마찬가지로 null값은 무시해준다. null도 사용하고 싶다면 case로 0으로 변환시키고 해야된다.

select avg(case when col is null then 0 else quantity end) as avg from sample;

3. Min, Max로 최솟값, 최댓값 구하기

min, max는 문자열과 날짜시간형에도 사용 가능하다. Null값을 무시하는건 다른 집계함수와 같다.

select min(col), max(col) from sample;

22강: 그룹화-group by

select * from table명 group by col1, col2, ...

1. group by로 그룹화

select col1 from sample group by col1;

이렇게 해주면 distinct와 같은 결과값이 나온다.

select name, count(name), sum(quantity) from sample group by name;

이렇게 해주면 name에 관해서 groupby가 되고 그 다음에 그에 따른 count와 sum이 나온다.

2. having 구로 조건 지정

집계함수에서는 where 사용 불가. 대신에 having을 사용한다. group by와 where 구의 내부처리 순서와 관계가 있다. where의 순서가 더 빠르기 때문에 오류가 일어날 수 밖에 없다. where->group by->select->order by로 진행된다.

select col1, count(col1) from sample group by name having count(co1)=1;

name중 count해서 1인것만 추출할 수 있다. where->group by->having->select->order by 순으로 처리된다. 별명은 사용 불가하다.(as로 별명을 설정하는 경우) mysql에서는 가능한거 같다.

3. 복수열의 그룹화

select col2 from sample group by col1; 

이런식으로 코드를 쓰면 에러가 발생한다.

select min(col1), name, sum(col2) from sample group by name;

이렇게 사용해야 에러가 발생하지 않는다.

select col1, name from sample group by col1, name;

이렇게 복수열을 group화 시킬 수 있다.

4. 결과값 정렬

group by로는 순서를 정렬할 수 없다. 따라서 order by를 사용해야한다.

select col1, count(co1), sum(col2) from sample group by col1 order by sum(col2) desc;

이런식으로 코드를 작성해주면 된다.

23강: 서브쿼리

서브쿼리는 select 명령에 의한 데이터 질의로, 상부가 아닌 하부의 부수적인 질의를 의미한다. 괄호를 묶어서 서브쿼리를 지정한다. where 구에서 가장 많이 사용된다.

1. delete의 where 구에서 서브쿼리 사용하기

delete from sample where a=(select min(a) from sample);

이런식으로 코드를 작성하면 min(a)값을 먼저 찾아주고 그 값을 없애준다. 그러나 mysql에서는 이 코드가 실행 불가능하다. delete 명령을 select로 바꿔주면 실행 가능하다.

delete from sample where a=(select a from(select min(a) as a from sample)as x);

이렇게 작성해주면 에러가 발생하지 않는다.

2. 스칼라값

서브쿼리 사용시 select 명령이 어떤 값을 반환하는지 주의깊게 볼 필요가 있다.

하나의 값, 복수의 행이 반환되나 열은 하나, 그리고 하나의 행이 반환되지만 열이 복수인 패턴, 복수의 행, 복수의 열이 반환되는 패턴이 있다.

3. select 구에서 서브쿼리 사용 문법적으로 서브쿼리는 하나의 항목으로 취급한다. 그러나 문법적으로 오류가 없으나 에러가 나는 경우가 있다. 이는 스칼라 값의 반환여부에 따라 생기는 현상

select
(select count(*) from sample1) as sq1,
(select count(*) from sample2) as sq2;

mysql에서는 from 생략이 가능하다.

4. set 구에서 서브쿼리 사용하기

update sample set=(select max(a) from sample);

update 함수 쓰면 a 열값들이 모두 a의 최댓값으로 변환된다.

5. from 구에서 서브쿼리 사용하기

select * from (select * from sample)sq;

이 형태를 nested 구조 또는 중첩구조라고 부른다. sq는 테이블의 별명이다. 별명을 붙여서 서브쿼리에 이름을 붙일 수 있다.

select * from (select * from sample) as sq;

별명을 as를 사용해서 붙였다.

select * from (select * from (select * from sample)sq1)sq2;

3단으로도 중첩 가능하다.

6. insert 명령과 서브쿼리

insert into smaple values(
(select count(*) from sample1),
(select count(*) from sample2)
);
insert into sample select 1,2;

이 문구는 insert와 select를 합친 문구이다. 이 구는 복사나 이동할 때 많이 사용함

insert into sample select * from sample1;

24강: 상관 서브쿼리

서브쿼리의 일종인 상관 서브쿼리를 exists 술어로 조합시켜서 서브쿼리를 사용할 수 있다. 이 술어를 사용하면 서브쿼리가 반드시 스칼라값을 반환할 필요가 없고, 단지 반환된 행이 있는지 확인해보고 있으면 참, 없으면 거짓을 반환한다.

1. exists

update sample1 set a='있음' where
exists (select * from sample2 where no2=no);

서브쿼리 부분이 update의 where 구로 행을 검색할 때마다 차례로 실행되는 느낌이다. 서브쿼리의 where구에는 no2=no 조건식이 있다. 이때 no가 3과 5일때만 반환한다.

2. not exists

위와 반대 케이스

update sample1 set a='없음' where
not exists (select * from sample2 where no2=no);

3. 상관 서브쿼리

위의 update 명령어(부모)에서 where로 묶은 부분이 서브쿼리(자식)가 된다. 이것을 상관 서브쿼리라 부른다. 상관 서브쿼리는 단독 서브쿼리와는 다르게 단독으로 실행 불가. 모두 같은 열로 되어 있으면 제대로 잘 동작하지 않는다.

update sample1 set a='있음' where
exists (select * from sample2 where sample2.no2=sample1.no);

이렇게 직접 입력해줘야 한다.

4. in

집합 비교시 =를 사용할 수 없기 때문에 in을 사용해서 비교해야한다. 서브쿼리 사용할 때 in을 많이 사용함. in은 오른쪽에 집합을 지정한다.

select * from sample where no in(3,5);

3,5에 관한 값들이 나온다.

in의 오른쪽을 서브쿼리로 지정가능하다.

select * from sample where no in
(select no2 from sampl2);

단 열이 복수로 지정되면 이 함수를 쓸 수 없다.

in에서는 null값을 무시하지 않는다. 그러나 이 값을 비교할 순 없다.