(ORACLE) NULL값을 치환하는 NVL, NVL2 함수

SQL을 사용하다 보면 NULL을 다른 결과로 치환하여 출력하는 문제가 가끔 나온다.

오라클에서는 이를 NVL 함수로 간단히 처리 가능한데 문제가 있다면 이 쿼리를 다른 DBMS에서 사용할 때 이다.

ORACLE : NVL

MYSQL : IFNULL

MSSQL : ISNULL

세 개의 DBMS 모두 사용하는 함수가 다른데 그렇기 때문에 서로 호환이 안된다.

NVL 함수의 사용법

1
2
3
4
5
-- 기본형
NVL(컬럼, NULL일 경우의 반환값)

NVL(컬럼, '') -- 컬럼의 값이 NULL일 경우 ''으로 치환함
NVL(컬럼, 0) -- 컬럼의 값이 NULL일 경우 0으로 치환함

예제

1
2
3
-- NAME 컬럼의 값이 NULL 일 경우 'No name'으로 치환
SELECT NVL(NAME, 'No name')
FROM ANIMAL_INS;

NVL2 함수의 사용법

기본적으로 NVL함수와 비슷하나 NULL값이 아닐때도 치환을 해준다

1
2
3
4
5
-- 기본형
NVL2(컬럼, NULL이 아닐경우의 반환값, NULL일 경우의 반환값)

NVL2(컬럼, '학생', '교사')
NVL2(컬럼, '대중교통', '자동차')

예제

1
2
3
-- DATETIME 컬럼의 값이 NULL 일경우 '정규직' NULL이 아닐경우 '계약직'
SELECT NVL(DATETIME, '계약직', '정규직')
FROM EMPLOYEE;

SQL리뷰 수업 코드정리-5

5일차 코드


Discus_Gold_Medal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- 성별, 연도 (2004, 2008, 2012), 현재 국가 (as Champion), 이전 국가
-- 조건 : Event명 'Javelin Throw', Medal = Gold
WITH Discus_Gold_Medal AS ( -- 아래 서브쿼리의 이름
SELECT
gender -- 성별, 연도, 종목, 국가(as 챔피언)
, year
, event
, country AS champion
FROM summer_medals -- 조회 테이블
WHERE
Year IN (2000, 2004, 2008, 2012) -- year컬럼이 2000, 2004, 2008, 2012 중에 하나이며
AND Medal = 'Gold' -- medal컬럼이 Gold이며
AND Event = ('Javelin Throw')) -- event컬럼이 Javelin Throw 인것

SELECT
gender -- 성별, 연도, 종목, 현재 1위국가,
, year
, event
, champion,
LAG(Champion) OVER -- LAG(컬럼, 숫자(기본값1)) = 괄호안의 컬럼의 이전값(숫자만큼)을 건너뛰고 가져와 컬럼을 새로 만듦,
(PARTITION BY gender ORDER BY Event ASC, Year ASC) AS -- 파티션을 gender로 분류, event와 year의 오름차순 정렬
Last_Champion -- as Last_Champion
FROM Discus_Gold_Medal -- 위에서 생성한 Discus_Gold_Medal 테이블에서 조회
ORDER BY gender asc, year ASC; -- gender, year의 오름차순 정렬

위 쿼리의 출력

서브쿼리가 정렬되어 출력되고, last_champion이 바로 전 대회의 우승국을 출력하는것을 볼 수 있다.

Athletics_Gold

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- 경기종목을 2개로 추가 ('100M', '10000M')

WITH Athletics_Gold AS ( -- 이하 서브쿼리의 이름
SELECT
gender -- 성별, 연도, 종목, 국가(as champion) 조회
, year
, event
, country AS champion
FROM summer_medals -- 조회 테이블
WHERE
Year IN (2000, 2004, 2008, 2012) -- year컬럼이 2000, 2004, 2008, 2012 중에 하나이며
AND Medal = 'Gold' -- medal컬럼은 Gold
AND Event IN ('100M', '10000M')) -- 100M 또는 10000M 종목인것

SELECT
gender -- 성별, 연도, 종목, 현재 1위국가
, year
, event
, champion,
LAG(Champion) OVER
(PARTITION BY gender, event ORDER BY Year ASC) AS -- 파티션을 gender와 event로 분류하고 year의 오름차순으로 정렬
Last_Champion -- as Last_Champion
FROM Athletics_Gold -- 위 쿼리에서 생성한 Athletics_Gold 테이블에서 조회
ORDER BY gender asc, event ASC, year ASC; -- gender, event, year의 순서대로 오름차순 정렬

위 쿼리의 출력

DiscusThrow_Gold

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- year, athlete, future_champion(3회 이후 챔피언)
-- 조건 : Medal =Gold / event = discus Throw / gender women / year >= 1992
-- lead(컬럼명, 3) over()
WITH DiscusThrow_Gold AS ( -- 이하 서브쿼리의 이름
select
year -- 연도, 선수 조회
, athlete
from summer_medals -- 조회 테이블
where
medal = 'Gold' -- 조건들 : medal컬럼이 Gold이며,
and event = 'Discus Throw' -- event컬럼이 Discus Throw,
and gender = 'Women' -- gender컬럼이 Women,
and year >= 1992 -- year컬럼이 1992 년 이후인것
)

select
year -- 연도, 선수, future_champion
, athlete
, lead(athlete, 3) over -- lead(컬럼, 숫자(기본값1)) = 괄호안의 컬럼의 이후값(숫자만큼)을 건너뛰고 가져와 컬럼을 새로 만듦
() as future_champion -- as future_champion
from DiscusThrow_Gold; -- DiscusThrow_Gold 테이블에서 조회

위 쿼리의 출력

이전까지 쿼리에서 사용된 LAG함수와 LEAD함수는 다음 절에서 설명한다.

LAG() 함수와 LEAD() 함수


LAG() 함수

LAG 함수의 사용 예

LAG함수는 보통 LAG(column, n(기본값1))의 형태인데 이는 현재 행 앞의 행에 있는 열의 값을 반환한다.

그렇기 때문에 위 사진에서 last_champion의 첫번째 결과는 null이 된다(앞의 결과가 없기때문)

이후 부터는 champion컬럼의 결과가 차례로 출력된다.

참고로 5번 열에서의 null은 gender를 partition by로 나누었고 현재 행의 앞의 열을 분리시킨상태이기 때문에 null값이 조회된다.


LEAD() 함수

LEAD 함수의 사용 예

기본적인형태는 LEAD(column, n(기본값1))의 형태이며,

LEAD 함수는 LAG 함수와는 반대로 현재 행 뒤의 행에 있는 열의 값을 반환한다.

사진에서 사용한 코드는 LEAD(athlete,3) 이므로 3칸 뒤의 열의 값을 반환한다.

이후 athlete컬럼의 결과가 차례로 출력되며 3번열 이후의 값은 존재하지 않기때문에 null이 반환된다.

SQL리뷰 수업 코드정리-4

4일차 코드


summer_medals 테이블

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
select * from summer_medals;

-- row_number()
-- 각 행에 숫자를 1, 2, 3, ..., N 형태로 추가한다.
-- 오름차순으로 기준을 진행한다.
-- 기본적 row_num만 추가
select
row_number() over() as row_num
, *
from summer_medals;

-- 올림픽 연도를 오름차순 순번대로 작성을 한다.
-- 연도 중복값 제거
-- 서브쿼리 : select distinct year from summer_medals order by year asc;
select
row_number() over() as row_num -- 각 행에 오름차순으로 숫자 추가 as row_num, year행 출력
, year
from
(select distinct year from summer_medals order by year asc) as years -- 중복값을 제거한 year 컬럼을 오름차순으로 출력 as years
order by year asc; -- select절의 컬럼들을 year컬럼의 오름차순으로 정렬

select * from summer_medals;

-- 운동선수 메달 갯수 쿼리 작성
with athlete_medals as (
select
athlete -- athlete, 전체 컬럼을 count하고 athlete로 묶음(group by절) as medal_counts
, count(*) medal_counts
from summer_medals
group by athlete
)
select
athlete -- athlete, medal_counts, medal_counts의 내림차순으로 숫자를 붙인 row_num 출력
, medal_counts
, row_number() over(order by medal_counts desc) as row_num
from athlete_medals
order by medal_counts desc -- select절의 컬럼들을 medal_counts의 내림차순으로 정렬
limit 10; -- 상위 10개만 출력

-- 남자 69 KG 역도 경기에서 금메달 리스트 추출.
-- Discipline = 'Weightlifting'
-- Event 69KG,
-- Gender
-- Medal
select * from summer_medals;
select distinct event, discipline, athlete, gender from summer_medals where event = '200M' and gender = 'Women' and medal = 'gold';

select
year -- 연도, 국가 as champion 출력
, country as champion
from
summer_medals
where
discipline = 'Weightlifting' and -- 종목 = 역도,
event = '69KG' and -- 세부종목 = 69KG,
gender = 'Men' and -- 성별 = 남자,
medal = 'Gold'; -- 금메달만, 상기 4개 조건 모두 만족하는결과만 출력

-- LAG

with weightligting_69_men_gold as (
select
year
, country as champion
from
summer_medals
where
discipline = 'Weightlifting' and
event = '69KG' and
gender = 'Men' and
medal = 'Gold'
)

select
year
, champion
, LAG(champion) over(order by year asc) as last_champion
from weightligting_69_men_gold
order by year asc;

-- Athletics, 200미터, 여자, 금메달 목록 가져오기
-- 나라 대신 선수이름 출력 year, 현재 챔피언 이름, 이전 챔피언 이름

with Athletics_200_Women_Gold as (
select
year
, athlete as champion
from
summer_medals
where
discipline = 'Athletics' and
event = '200M' and
gender = 'Women' and
medal = 'Gold'
)

select
year
, champion
, lag(champion) over(order by year asc) as last_champion
from Athletics_200_Women_Gold
order by year asc;

-- partition by 함수
-- partition by 미적용
WITH Discus_Gold_Medal AS (
SELECT
Year, Event, Country AS Champion
FROM summer_medals
WHERE
Year IN (2004, 2008, 2012)
AND Gender = 'Men' AND Medal = 'Gold'
AND Event IN ('Discus Throw', 'Triple Jump')
AND Gender = 'Men')

SELECT
YEAR, Event, Champion,
LAG(Champion) OVER
(ORDER BY Event ASC, Year ASC) AS Last_Champion
FROM Discus_Gold_Medal
ORDER BY Event ASC, Year ASC;

-- partition by 적용
WITH Discus_Gold_Medal AS (
SELECT
Year, Event, Country AS Champion
FROM summer_medals
WHERE
Year IN (2004, 2008, 2012)
AND Gender = 'Men' AND Medal = 'Gold'
AND Event IN ('Discus Throw', 'Triple Jump')
AND Gender = 'Men')

SELECT
YEAR, Event, Champion,
LAG(Champion) OVER
(PARTITION BY Event ORDER BY Event ASC, Year ASC) AS
Last_Champion
FROM Discus_Gold_Medal
ORDER BY Event ASC, Year ASC;

SQL리뷰 수업 코드정리-3

3일차 코드


languages 테이블

couintries 테이블

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
-- 서브쿼리 쓰는 방식
-- where 절 서브쿼리
-- select 절 서브쿼리
-- from 절 서브쿼리

select * from languages;
select * from countries;

-- 질문 : 각 나라별 언어의 갯수 구하기
-- Table: languages
select code, count(*) as lang_num -- 국가 코드, 모든행을 카운트해 lang_num 으로 출력
from languages -- 사용한 테이블
group by code; -- 국가 코드로 묶을것
-- 결과 : 각각의 국가 코드로 묶인 lang_num 출력

-- 질문, country로 변경하고, 언어의 갯수 구하기
-- lang_num을 내림차순으로 정렬함.
-- 이 쿼리서 from절 서브쿼리 사용
select local_name, subquery.lang_num -- countries 테이블의 local_name, (as)subquery 에서 lang_num을 각각 출력
from countries -- 테이블은 countries 와 다음의 서브쿼리
, (select code, count(*) as lang_num -- 전 질문의 쿼리를 가져와 'subquery' 명칭을 붙임
from languages
group by code) as subquery
where countries.code = subquery.code -- countries.code 와 subquery.code가 매칭이 될 경우만 조회
order by lang_num desc; -- lang_num을 내림차순으로 정렬
-- 결과 : countries.local_name과 subquery.lang_num이 각각 lang_num의 내림차순으로 출력

--
select * from economies
where year = 2015;

-- 코드별 inflation_rate
-- 각 대륙별, 각 나라별 inflation_rate
-- 각 대륙에서 inflation_rate가 가장 높은, inflation_rate를 출력

SELECT name, continent, inflation_rate -- name, continet, inflation_rate 를 조회
FROM countries -- countries 테이블
INNER JOIN economies -- inner join = 기준테이블, 조인테이블 모두에 해당 값이 존재할 경우 메인쿼리 조회
on countries.code = economies.code -- economies 와 countries.code = economies.code 에 겹치는 값이 있는지
WHERE year = 2015 -- year항목이 2015이고
and inflation_rate in ( -- inflation_rate 항목에 다음 서브쿼리의 값이 있는지
SELECT MAX(inflation_rate) AS max_inf -- 가장 큰 inflation_rate를 조회
FROM ( -- 다음의 서브쿼리에서
SELECT name, continent, inflation_rate -- name, continent, inflation_rate 조회
FROM countries -- countries 테이블
INNER JOIN economies -- economies 와
on countries.code = economies.code -- countries.code = economies.code 에 겹치는 값이 있는지
WHERE year = 2015) AS subquery -- year = 2015인 것만 조회 ) subquery로 명명
GROUP BY continent); -- 바로 위에서 출력한 서브쿼리를 continent로 묶음
-- 결과 : countries테이블의 name, continent, inflation_rate 조회 group by 때문에 대륙별로 한 나라씩만 조회되었고 조회된 나라의 기준은 inflation_rate가 가장 높은 국가

마지막 쿼리의 출력 결과

첫번째와 두번째 쿼리는 직접 작성하지는 못해도 해석은 할 수 있었는데 마지막 쿼리는 정말이지 복잡했다.
강의 뿐만 아니라 책도 구매해서 SQL를 더 파야 할 듯.

SQL리뷰 수업 코드정리-2

2일차 코드 (서브쿼리 기본)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
--실제 보유하고 있는 과일 데이터
select * from real_amount; -- 테이블값 있음, 위 이미지 첫번째 테이블

-- 카운터 컴퓨터에서 추정한 과일 데이터
select * from assumption_amount; -- 테이블값 있음, 두번째 테이블

-- 외상 데이터
select * from exception; -- 테이블값 없음, 세번째

-- 기본적으로 서브쿼리에서 true가 반환되어야 메인쿼리가 실행되는듯
-- exists(서브쿼리) == 서브쿼리의 결과가 한건이라도 존재할 경우 True 없으면 False 리턴
-- 카운터에는 데이터 존재 / 외상 데이터 현재 없음
select * from real_amount -- 현재 과일 데이터 출력
where exists ( -- 위의 exists 설명 참조
select * from assumption_amount -- 컴퓨터 추정 과일데이터
);
-- 결과 : 컴퓨터에서 추정한 과일 데이터가 존재하니 exists == true 반환, 그러므로 메인쿼리가 실행됨

select * from real_amount -- 현재 과일 데이터 출력
where exists ( -- 위의 exists 설명 참조
select * from exception -- 외상데이터
);
-- 결과 : 외상데이터 조회시 테이블값이 없기 때문에 exists == false 반환, 메인쿼리가 실행되지 않음
-- SQL의 아웃풋 창에는 select * from exception이 출력

-- IN 연산자 / NOT IN 연산자
-- IN 연산자 : 하나이상의 값이 도출이 되면 true
select * from real_amount -- 현재 과일 데이터 출력
where amount in ( -- amount(메인쿼리의 테이블에서 값을 받아오는 것으로 추정)값에 10, 20, 30 이 있을경우 true
10, 20, 30
);
-- 결과 : real_amount 테이블의 amount 컬럼에 10과 30이 존재하기 때문에 메인쿼리가 실행되어 현재 과일데이터가 출력됨

-- ANY 연산자
select * from real_amount -- 현재 과일 데이터 출력 (3)
where 10 = any ( -- 서브쿼리의 출력에 10이 있을 경우 (2)
select amount from assumption_amount
-- assumption_amount 테이블의 amount 컬럼을 출력 (1)
);
-- 결과 : assumption_amount 테이블의 amount 컬럼에 10이 존재하기 때문에 real_amount 출력

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
select * from populations; -- 위 테이블 이미지

-- 기본적인 집계함수
-- avg(*) NULL 값이 아닌 모든 입력 값의 평균

select avg(life_expectancy) from populations; -- 모든 life_expectancy의 평균값 출력

-- count(*) 입력한 행의 총 갯수
select count(*) from populations; -- populations 테이블의 모든 행 갯수 - 434

-- count(컬럼명) NULL 값이 아닌 해당 컬럼 행의 갯수
select count(life_expectancy) from populations; -- populations 테이블의 NULL이 있는 행을 제외한 life_expectancy 컬럼의 갯수 - 398

-- max, min, sum -- 모두NULL 값이 아닌 해당 컬럼 행만 계산
select max(life_expectancy) from populations;

select min(life_expectancy) from populations;

select sum(life_expectancy) from populations;

-- 기대수명이 가장 높은 country code
select country_code, life_expectancy -- country_code, life_expectancy 출력 (5)
from populations -- populations 테이블의(4)
where life_expectancy = ( -- (2)와 동일한 life_expectancy값을 가진 행의 (3)
select min(life_expectancy) -- life_expectancy컬럼의 최솟값(2)
from populations -- populations 테이블의 (1)
);
-- 결과 : populations 테이블의 life_expectancy컬럼의 최소값과 동일한 life_expectancy를 가진 country_code, life_expectancy를 populations 테이블에서 찾아 출력

-- 삼중쿼리
-- 집계함수는 where절에서 사용 불가이기 때문에 서브쿼리 사용
select country_code -- country_code 출력 (8)
from populations -- populations테이블의 (7)
where code = ( -- (5)에서 선택된 테이블의 행중에 code 컬럼과 같은값을 가진 행 (6)
select * -- (4)에서 선택된 테이블의 모든 컬럼 조회 (5)
from countries -- countries 테이블 (4)
where life_expectancy = ( -- (2)와 동일한 life_expectancy값을 가진 행 (3)
select min(life_expectancy) -- life_expectancy컬럼의 최솟값 (2)
from populations -- populations 테이블의 (1)
));
-- 복잡하다... 설명을 못해서 그렇기도 하지만, 차라리 SQL로 보는게 낫지 한글로 풀어설명하는게 더 복잡하다.

-- 조건 1. 2015년 전체 국가의 평균 수명 계산
-- 조건 2. 모든 데이터를 조회합니다.
-- 조건 3. 2015년 평균 기대수명의 1.15배보다 높도록 조건을 설정합니다.

-- 이번엔 거꾸로 과정 작성
select * -- 모든 컬럼 출력 (1)
from populations -- populations 테이블의 (2)
where life_expectancy > 1.15 * ( -- 단, life_expectancy가 서브쿼리 값의 1.15배보다 큰것만 출력 (3)
select avg(life_expectancy) -- life_expectancy의 평균값 출력(4)
from populations -- populations 테이블의 (5)
where year = 2015) -- year 컬럼이 2015인것들로만 평균값 출력(6)
and year = 2015; -- (3)의 and조건 추가절, year가 2015 일것.
-- 결론 : 2015년도의 평균life_expectancy * 1.15 보다 크고, year 가 2015인 행의 모든 컬럼 출력
-- 간단한 편..



select * from cities; -- name

select * from countries; -- capital

-- 메인쿼리
-- citi 테이블에서, name, country_code, urban_pop
-- urban_pop 내림차순 정렬
-- 상위 5개만 출력
-- 서브쿼리
-- city 테이블에 name과 countries capital 매칭이 되는 애들만 조회
select name, country_code, urbanarea_pop -- 각 컬럼 출력
from cities -- cities 테이블에서 조회
where name in (select capital from countries) -- name컬럼 내부에 서브쿼리의 값과 같은값이 있는 경우만
order by urbanarea_pop desc -- urbanarea_pop 컬럼 내림차순으로 정렬
limit 5; -- 상위 5개만

-- 결과물을 동일하게
-- 두개의 테이블을 JOIN
SELECT countries.name AS country, COUNT(*) AS cities_num
FROM cities
INNER JOIN countries
ON countries.code = cities.country_code -- 테이블 교집합
GROUP BY country -- country의 항목으로 묶어줌
ORDER BY cities_num DESC, country -- cities_num 컬럼을 내림차순으로 정렬, country 컬럼 출력
LIMIT 9; -- 상위 9개만

-- 서브쿼리를 where --> select 절로 옮긴 결과
select
countries.name as country
, (select
count(*)
from cities
where countries.code = cities.country_code) as cities_num
from countries
order by cities_num desc, country
limit 9;
-- 안보던 형식이라 그런지 더 복잡해 보인다.

PostgreSQL Data 불러오기, 내보내기

DB를 사용하다보면 데이터를 불러와야할 일도, csv파일 등으로 내보내야 할 일도 있다.

처음 사용하는 사용자에겐 이 과정이 상당히 복잡하기 때문에 배운것을 기록 해 둘겸 남에게 쓰임새 있게 쓰이길 바라며 포스팅 시작.

사전 준비

  • DB 로그인이 가능한 pgAdmin(PostgreSQL 관리 프로그램)
  • 사용 가능한 .csv, .dump 파일

Data import

좌상단의 File > Preferences > Paths > Binary paths 에서

EDB Advanced Server Binary Path가 아닌 PostgreSQL Binary Path 에 위 사진처럼 자신의 이하경로/PostgreSQL/버전/bin 을 입력해준다

잘 입력했다면 Set as default를 누르고 Save.

이젠 적용할 테이블에 우클릭을 한 후, Import/Export… 을 클릭해준다.

Import/Export 는 Import로

Filename은 테이블에 적용하고 싶은 파일을 찾아주고

Header를 Yes로

Delimiter는 파일마다 다를수 있는데 필자의 경우 파일을 메모장으로 열어봤을때 구분이 쉼표로 되어있기때문에 ,로 골라주었다.

OK로 적용해주고

테이블 리프레쉬~

이후 Query Tool을 열어 테이블을 조회해주면 깔끔히 적용된 모습이 출력된다.

Data export

PostgreSQL의 데이터 export 방법에는 두가지가 있다.

첫째는 pgAdmin 을 통해 위 사진에 있는 Save results to file 버튼을 클릭하여 csv로 다운로드 받는법.

이는 직관적이고 쉽지만 항상 pgAdmin을 통해 다운받을수는 없으니 다른 방법도 알아보려 한다.

둘째는 CMD 를 통해 csv를 다운받는 법이다.

그러기 위해서는 미리 원하는 형식의 sql파일을 만들어 놓아야 한다.

가령 cities 테이블 전체를 내보내려면

1
SELECT * FROM cities;

가 작성된 sql 파일을 미리 만들어 놓아야 한다.

이번 포스팅에서는 이 파일 이름이 cities.sql이라 가정하고 포스팅을 작성한다.

이후 CMD에서 할 일은 다음과 같다.

먼저 파일이 있는 곳으로 이동해야 한다

1
cd [cities.sql이 있는 경로]

이제 다음의 명령을 입력해 cities.sql의 출력값을 그대로 csv로 출력하면 된다

1
2
3
4
5
6
7
8
9
10
psql -U postgres -d postgres -f cities.sql -o cities.csv -F ',' -A -t

-- 명령어의 뜻은 다음과 같다.
-- -U = 데이터베이스 사용자 이름
-- -d = 연결할 데이터 베이스 이름
-- -f = 파일 내부의 지정한 명령을 실행후 끝냄
-- -o = 쿼리 결과를 파일(또는 |파이프)로 보냄
-- -F = unaligned 출력용 필드 구분자 설정(기본값: "|")
-- -A = 정렬되지 않은 표 형태의 출력 모드
-- -t = 행만 인쇄

어후 복잡하다.

그래도 psql --help를 입력하면 모든 명령어가 출력되니 참고하며 쓰면 된다.

위의 명령어를 입력하면 DB의 암호 입력창이 나오는데 DB를 만들때 입력했던 암호를 입력하면 csv생성이 완료된다.

dump파일 업로드

dump파일이 있는 폴더로 이동하고 다음 명령 입력시 데이터 베이스에 테이블 각각 생성됨.
psql -U postgres -d postgres -f function_example.dump
유저네임, DB이름, 파일이름에따라 명령어를 알맞게 바꿔주어야 함.
명령어에 대한 설명은 바로 위에 있고, psql --help를 해도 볼 수 있음.

SQL리뷰 수업 코드정리-1

1일차 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
-- 전체 테이블 조회
select * from subway;

-- 테이블 생성
create table develop_book(
book_id integer
, date date
, name varchar(80)
);

-- 등록된 테이블 리스트 조회
-- CMD 창에서 \dt 실행하면 동일한 리스트 확인 가능
SELECT * FROM pg_catalog.pg_tables
WHERE schemaname != 'pg_catalog' AND
schemaname != 'information_schema';

-- 테이블 삭제
drop table develop_book;

-- 테이블 생성
create table develop_book(
book_id integer
, date date
, name varchar(80)
);

-- 데이터 자료 추가하기
insert into develop_book values(1, '2021-12-22', 'SQL 레시피');

-- 큰 따옴표 입력
insert into develop_book values(2, '2021-12-23', '"자바의 정석"');

-- 작은 따옴표 입력
insert into develop_book values(3, '2021-12-24', '''자바의 정석''');

-- Let's go 입력
insert into develop_book values(4, '2021-12-25', 'I''am book');

-- 조회 하기
select * from develop_book;

-- 테이블에 자료 여러 개 추가하기
insert into develop_book values
(5, '2021-12-30', '책1'),
(6, '2021-12-30', '책2'),
(7, '2021-12-30', '책3'),
(8, '2021-12-30', '책4');

-- 조회 하기
select * from develop_book;

-- 컬럼 선택 조회
select book_id, name from develop_book;

-- Limit 명령어
select * from develop_book limit 3;

-- OFFSET 명령어 추가
-- ~번째 인덱스부터 시작
select * from develop_book limit 5 offset 2;

-- ORDER BY
-- 오름차순
select * from develop_book
order by name asc;

select * from develop_book
order by name desc;

-- WHERE 조건문
select * from develop_book
where book_id = 5;

select * from develop_book
where book_id <> 5; -- 5 제외

-- AS 명령어
select name as 책제목 from develop_book;

-- Coalesc 함수
-- 데이터 조회 시, NULL 값을 다른 기본 값으로 치환
-- ex) NULL --> "데이터 없음"

insert into student_score(name, score)
values ('Hello', NULL), ('Hi', NULL);

-- 조회
select
id
, name
, score
, case
when score <= 100 and score >= 90 then 'A'
when score <= 89 and score >= 80 then 'B'
when score <= 79 and score >= 70 then 'C'
when coalesce (score,0) <= 69 then 'F'
end
from student_score;

-- 결측치 처리
select
students
, coalesce((12/nullif(students, 0))::char, '나눌 수 없음') as column8
from division_by_zero;