sql기초지식-6

아기코딩단2·2022년 3월 18일
0

데이터를 컬럼으로 뺀다는 건 데이터를 따로 뽑는다는 것

이거하면 이게 뜰 거고 그런 식으로 말하면 됨

뽑아질 데이터를 선택하는 것을 projection 이라고 함

FK = PK 식별관계

/ 모든 데이터를 가져온다./
select all loc from room; -- all 컬럼명 from 테이블 명

/ all은 생략할 수 있다/
select loc from room;

/ 중복 값을 한 개만 추출할 때 distinct 를 붙인다./
select distinct loc from room;
이렇게하면 강남강남 서초서초서초 에서 강남, 서초로 나옴

/ 순서를 지정하지 않으면 기본 인덱스 컬럼을 기준으로 정렬한다./
select rno, loc, name
from room;

from 절 다음에 order by 절 붙이면 정렬할 컬럼을 선택하면 됨
asc 은 오름차순으로 정렬해라
select rno, loc, name
from room
order by name asc;
근데 asc 는 생략가능

from - order by - select 순서로 실행됨
내림차순은 desc로 써주면 됨

별명 주고싶으면 실제 컬럼이름 as 주고싶응ㄴ 별명(중간에 공백 들어가면 안됨)
as 생략가능

select concat(name, '(', loc, ')')
from room; 할 때 별명안주면 합친 이름으로 나옴

select concat(name, '(', loc, ')') title
from room; t
=>title 에 별명 주면됨 & as 생략가능

----------둘의 차이------------
select count(*) cnt
from room
where loc='서초';

/ count()를 호출할 때 컬럼 이름을 지정하면
해당 컬럼의 값이 null 이 아닌 데이터만 카운트한다.
/
select count(loc) cnt
from room;


/ select 결과 합치기
union : 중복 값 자동 제거
/
select distinct bank from stnt
union
select distinct bank from tcher;

/ union all: 중복 값 제거 안함/
select distinct bank from stnt
union all
select distinct bank from tcher;


oracle 은 minus 라는 기능 존재(차집합 연산)
근데 mysql 은 지원안함ㅠ조건으로 나눠서 다시 빼줘야함
=>
/ mysql 의 차집합 문법이 존재하지 않는다
따라서 다음과 같이 기존의 SQL 문법을 사용해서 where 절의 조건으로 처리해야한다.
/
select distinct bank
from stnt

where not bank in (select distinct bank from tcher);

/교집합 문법/
select distinct bank
from stnt
where bank in (select distinct bank from tcher);


select : join

  1. CROSS 조인(=Cartesian product)
    A ~ D
    1~ 3
    이렇게 있으면 총 12개의 결과물이 나옴

  2. inner join - 지정한 두개의 컬럼값이 같을 때만 두 레코드를 조인함
    아반떼(1) (1)현대
    소나타(1)
    K7(2)
    소울(2)
    sm5(3)
    이렇게 잇으면 자동차 회사 기준으로 join을 맺는 거임
    아반떼 - 현대
    소나타 - 현대
    K7 - 기아
    소울 - 기아

  3. outer join (두가지 기준 존재 left, right)
    아반떼(1) (1)현대
    소나타(1)
    K7(2)
    소울(2)
    sm5(3)

3-1 left outer join

왼쪽기준으로 맞춤

아반떼(1) (1)현대
소나타(1) (4)쌍용
K7(2)
소울(2)
sm5(3)
join 하면 쌍용과 연결되는 게 없기 때문에 쌍용은 안만들어짐

3-2 right outer join

오른쪽 기준으로 맞춤

아반떼(1) (1)현대
소나타(1)
K7(2)
소울(2)
sm5(3)
join 하면 쌍용과 연결되는 게 없어도 쌍용은 만들어져서 null이 됨


크로스 조인 문법
select memb.mno member_no, name, stnt.mno student_no, work, bank
from memb cross join stnt;

/ 예전 문법 /
select memb.mno member_no, name, stnt.mno student_no, work, bank
from memb, stnt;

natural join: 같은 이름을 가진 컬럼 값을 기준으로 레코드를 연결한다.
컬럼명이 다르면 natural join 쓸 수 없음
이름이 같아야함
natural join 은 원치않는 데이터도 join이 될 수 있음

natural join 의 문제점
1) 두 테이블의 조인 기준이 되는 컬럼 이름이 다를 때 연결되지 못한다.
2) 상관 없는 컬럼과 이름이 같을 때 잘못 연결된다.
3) 같은 이름의 컬럼이 여러 개 있을 경우 잘못 연결된다.
모든 컬럼의 값이 일치할 경우에만 연결되기 때문이다.


natural join 이 무효할 경우

1) 부모테이블의 PK컬럼명과 자식테이블의 FK컬럼명이 다를 경우
=> 이 경우는 조인 안됨
2) 부모 테이블의 PK컬럼명과 자식 테이블의 다른 컬럼명이 같을 경우(상관없는 컬럼과 이름이 같을 경우)
=> 이에 대한 해결책
=> 회원 join 게시글 on 회원.no =게시글.writer_no => 이 두개가 같을 경우 묶어라

3)상관없는 컬럼이 이름이 같기 때문에 조인 조건으로 사용되는 문제의 해결책
=> 회원 join 게시글 using (mno) => 조인 기준이 되는 컬럼을 명시적으로 지정한다.

select m.mno, name, s.mno, work, bank
from memb m inner join stnt s on m.mno=s.mno; <= 여기서 inner 생략가능

/ 예전의 조인 문법 = inner join /
select m.mno, name, s.mno, work, bank
from memb m, stnt s
where m.mno=s.mno;

기준이 되는 테이블의 컬럼이 같을 경우만 join 하는 게 inner join 임
=> 데이터 누락되는 상황 발생 가능성

select
l.lno,
l.titl,
r.rno,
r.loc,
r.name
from lect l left outer join room r on l.rno=r.rno;
왼쪽 테이블인 lect를 기준으로 room 데이터를 연결한다.
만약 lect와 일치하는 데이터가 room에 없더라도
lect 데이터를 출력한다!
아니면 right 를 써서 기준을 정해줄 수 있음


inner 은 null 출력못함 근데 outer 사용하면 기준점이 생겨서 null 이 출력가능
join은 기본기술임 꼭 알아야함
inner 안붙어있으면 기본이 inner join

sql - Exam07_5.sql

join 의 기준은 FK 가 기준

select 결과에는 테이블명이 안붙음
없는 데이터가 없을 수 없으면 inner join 사용
없는 데이터가 있을 수 있다면 outer join 사용
=> left, right 기준 생각 잘하기

coalesce(r.name, '') room_name
=> NULL 대신 빈문자열

컬럼간의 이름이 같을 경우 별명을 주면 됨

select 방식은 하나의 데이터에 대해서 각각 선택하기 때문에 join보다 느리다.
subQuery 의 결과는 항상 하나인지 확인해줘야함 coulmn 은 하나만 될 수 있음
=>concat 쓰면 합치기 가능하긴 함
where 절에 들어있는 select 의 경우 계속해서 꺼내서 값을 비교함(근데 전부 계속해서 꺼낸다는 뜻은 아님(어느정도의 최적화))=>그래서 join보다 느림
join >>>> subQuery

subQuery

inner join (서브쿼리) 가상 테이블의 이름(안올수도 잇음)

where 절, from 절 안에 subQuery 넣을 수 있음

그룹단위로 묶은 다음 연산을 수행함 group by => 계산

group by 사용하면 Aggregate Functions 에 있는 함수 사용가능

group by 랑 having 이 짝임 짝

=----------------------------------------
having의 조건은 그룹으로 묶을 때 사용한 컬럼이어야 한다.

-- 다음은 실행 오류!
select
r.loc,
count(*) as cnt
from
room r
group by
r.loc
having
r.name = '301'; -- having의 조건은 그룹으로 묶을 때 사용한 컬럼이어야 한다.

having 절에 집합함수는 사용할 수 있다.

profile
레거시 학살자

0개의 댓글