You are on page 1of 158

디비디비 딥 SQLite

DBDB, Deep SQLite

곽승주(jim.kwag@outlook.com)
Introduction
Database & SQLite
a collection of data
데이터베이스란?

● 자료의 구조적인 모임
● 주제나 목적에 관련된 정보들의 집합체
● 워드나 엑셀로 정리한 주소록도 일종의 데이터베이스
● 자료가 많으면 검색이나 관리에 많은 시간이 필요하다. 가령 월별로
매출현황을 서로 다른 파일에 나누어서 정리하는 경우 특정 지점에
관련된 일정기간의 매출현황을 분석하려면 12개의 파일을 모두 열어
관련정보를 찾아야 한다.
● 여러 사용자가 공유하는 데이터의 경우 자료의 전달이나 최신자료
업데이트 등에 불편하다.
DBMS와 RDBMS

● DBMS는 데이터를 저장하고 관리하는 시스템


● RDBMS는 DBMS의 한 종류이며, 데이터를 구조적(RDB , 필드와
레코드로 구성된 테이블과 테이블간의 연결되는 형태)으로 저장하고
관리하는 시스템
● RDBMS : Oracle, MS-SQL Server, Informix, MySQL, MariaDB,
MS-Access, SQLite 등등
관계형 데이터베이스(RDBMS)

● 필드와 레코드로 표현한 데이터를 RDB또는 테이블(Table)이라고 함


● 필드와 레코드는 워크시트의 열과 행(Column & Row)에 해당
SQLite 장점

MySQL나 PostgreSQL와 같은 DBMS이지만, 서버가 아닌 비교적 가벼운


파일형 데이터베이스이다. 일반적인 RDBMS에 비해 대규모 작업에는
적합하지 않지만, 중소규모라면 속도에 손색이 없다. 데이터를 저장하는 데
하나의 파일만을 사용하는 것이 특징이다. 구글 안드로이드 운영체제에 기본
탑재된 데이터베이스이기도 하다.

● 설치 과정이 없고, 설정 파일도 존재하지 않는다.


● 테이블, 인덱스, 트리거, 뷰 등을 포함한 완전한 데이터베이스가 디스크
상에 단 하나의 파일로 존재
● 개인적 또는 상업적 목적으로 사용가능
SQLite 와 관련 소프트웨어

SQLite를 사용하려면 몇 가지를 다운 받아 설치한다.

● SQLite 공식 홈페이지 : https://www.sqlite.org/index.html


○ https://www.sqlite.org/2018/sqlite-tools-win32-x86-3240000.zip
● SQLite Studio : https://sqlitestudio.pl/index.rvt
● DB Browser for SQLite : https://sqlitebrowser.org/
● ODBC 드라이버 (오피스버전에 맞춰 설치):
○ (32bit) http://www.ch-werner.de/sqliteodbc/sqliteodbc.exe
○ (64bit) http://www.ch-werner.de/sqliteodbc/sqliteodbc_w64.exe

(이번 강의는 32비트 버전을 기준으로 진행합니다 )


SQLite 다운로드 및 설치

Windows용 프로그램중 맨 아래의 zip을 다운 받아 적당한 폴더(가령 C:\SQLite)에 압축을 풀면 된다. 위의


프로그램은 커맨드라인에서 입력하는 것으로, 편리하게 윈도용 프로그램을 이용하려면 GUI프로그램인
SQLite Studio를 사용할 수 있다. 이번 강의에서는 커맨드라인 툴을 이용한다.
SQLite3 맛보기
1. 명령프롬프트를 열어 압축을 푼 폴더(C:\SQLite)로 이동한다
2. SQLite3.exe 입력하고 엔터
명령 프롬프트

c:\sqlite>sqlite3
SQLite version 3.23.0 2018-04-02 11:04:16
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
SQLite3 맛보기
1. .help 를 입력하면 여러 가지 명령어들에 대한 간략한 소개를 보여준다
2. .help 입력하고 엔터
명령 프롬프트

sqlite> .help
.archive ... Manage SQL archives: ".archive --help" for
details
.auth ON|OFF Show authorizer callbacks
.backup ?DB? FILE Backup DB (default "main") to FILE
.bail on|off Stop after hitting an error. Default OFF
.binary on|off Turn binary output on or off. Default OFF
.cd DIRECTORY Change the working directory to DIRECTORY
...
SQLite3 맛보기
1. 종료하려면 .quit 명령을 사용한다
2. .quit 입력하고 엔터
명령 프롬프트

sqlite> .quit

c:\sqlite>
SQLite Select
SELECT 문은 가장 많이 사용하는 SQL 문으로 간단하게 사용할 수 도 있지만 여러 SQL구문중 가장
복잡하기도 하다.

명령 프롬프트 ● select 문은 간단한 연산도 할 수 있다


sqlite> select 1+1; ● 끝에는 세미콜론(;)을 붙여 마지막임을
2
알려 주어야 한다
sqlite> select
...> 1+1;
2
sqlite> select 10/5, 2*4;
2|8
SQLite Select

SELECT 구문

1. SELECT DISTINCT column_list 1. DISTINCT 중복되지 않는 레코드


2. FROM table_list 2. FROM 조회할 테이블
3. JOIN table ON join_condition 3. JOIN ON 여러 테이블을 묶어서 조회
4. WHERE row_filter
4. WHERE 조건절, 결과를 필터링
5. ORDER BY column
5. ORDER BY 결과를 정렬
6. LIMIT count OFFSET offset
6. LIMIT OFFSET 돌려주는 레코드의 갯수 제한
7. GROUP BY column
7. GROUP BY 레코드를 그룹으로 묶어 집계함수
8. HAVING group_filter;
사용시
8. HAVING 그룹 필터링
SQLite Select
그러나 간단한 SELECT구문 위주로 진행을 할 예정

명령 프롬프트 가장 간단한 형태의 SELECT 구문은 한 개의


SELECT column_list 테이블에서 테이블내의 필드를 조회하는 것이다.
FROM table;
앞서 말한 바와 같이 쿼리문의 끝에는 세미콜론(;)
으로 마무리하여야 한다.
SQLite Select
Tracks 라는 테이블이 있고, 그 안에 trackid, name 등의 필드가 있을 때 테이블의 내용을 조회하려면
SQLite Select
일부 필드만 조회하는 경우 필드명을 나열하고, 전체를 조회하는 경우 애스테리크(*)를 사용한다

명령 프롬프트

SELECT
trackid,
name, 명령 프롬프트
composer,
SELECT
unitprice
*
FROM
FROM
tracks;
tracks;
SQLite Select Distinct
조회결과중에는 중복된 레코드가 있을 수 있다. DISTINCT 키워드를 필드명앞에 붙이면 중복되지
않는 레코드를 반환한다.

명령 프롬프트 조회결과에는 NULL값이 나올 수 있다. NULL값은


SELECT DISTINCT 정보가 없거나 이용할 수 없음을 의미한다.
column_list
DISTINCT는 NULL도 값으로 인정하고 존재하는
FROM
table; 경우 NULL을 출력한다
SQLite Select Distinct
아래와 같은 customers 테이블이 있고 City 필드를 다음과 같이 조회하면 오른쪽 결과와 같이 중복된
도시이름이 나오게 된다

명령 프롬프트

SELECT
city
FROM
customers
ORDER BY
city;
SQLite Select Distinct
중복되지 않는 도시이름을 조회하려면 다음과 같이 DISTINCT를 사용한다

명령 프롬프트

SELECT DISTINCT
city
FROM
customers
ORDER BY
city;
SQLite Select Distinct
DISTINCT는 여러 개의 필드를 사용하는 경우에도 레코드가 중복되지 않는 결과를 돌려준다

명령 프롬프트

SELECT DISTINCT
city,
country
FROM
customers
ORDER BY
country;
SQLite Order By
ORDER BY는 지정한 필드를 키(key)로 삼아 레코드를 오름차순 또는 내림차순으로 정렬한다

명령 프롬프트 오름차순 정렬은 ASC, 내림차순 정렬은 DESC를


SELECT 사용한다. 왼쪽의 구문에서는 column_1을
column_list
기준으로 오름차순(ASC)으로 정렬한 결과에서
FROM
table 다시 column_2를 기준으로 내림차순(DESC)으로
ORDER BY 정렬한다.
column_1 ASC,
column_2 DESC;
SQLite Order By
ORDER BY는 지정한 필드를 키(key)로 삼아 레코드를 오름차순 또는 내림차순으로 정렬한다

명령 프롬프트

SELECT 왼쪽 쿼리는 albumid


name,
필드를 기준으로
milliseconds,
albumid 오름차순 정렬을 한다
FROM
tracks
ORDER BY
albumid ASC;
SQLite Order By
ORDER BY는 지정한 필드를 키(key)로 삼아 레코드를 오름차순 또는 내림차순으로 정렬한다

명령 프롬프트

SELECT 왼쪽 쿼리는 albumid


name,
필드를 기준으로
milliseconds,
albumid 오름차순 정렬을 한 후
FROM milliseconds필드를
tracks
ORDER BY 내림차순으로
albumid ASC, 정렬한다
milliseconds DESC;
SQLite Order By
ORDER BY는 지정한 필드를 키(key)로 삼아 레코드를 오름차순 또는 내림차순으로 정렬한다

명령 프롬프트

SELECT 필드이름 대신
name,
조회하려는
milliseconds,
albumid 필드순서번호를
FROM 사용할 수 있다
tracks
ORDER BY
3 ASC,
2 DESC;
SQLite Limit
쿼리의 결과로 돌려받는 레코드의 갯수를 지정한다

명령 프롬프트 명령 프롬프트

SELECT SELECT
column_list trackId,
FROM name
table FROM
LIMIT row_count; tracks
LIMIT 10;
SQLite Limit Offset
Limit과 함께 Offset을 같이 사용할 수 있는데, 가령 처음 10개의 레코드이후 다음 10개의 레코드를 얻으려
한다면 Offset을 같이 사용할 수 있다

명령 프롬프트 명령 프롬프트

SELECT SELECT
column_list trackId,
FROM name
table FROM
LIMIT row_count tracks
OFFSET offset; LIMIT 10 OFFSET 10;
SQLite Limit과 Order By
조회를 할 때 레코드를 특정 필드를 기준으로 정렬한 결과를 얻으려고 하는 경우가 많다. 그래서 Limit과
Order By를 같이 사용한다. Order By가 Limit보다 먼저 오면 전체 레코드를 정렬하고 Limit만큼의 레코드를
돌려준다.

명령 프롬프트 명령 프롬프트

SELECT SELECT
column_list trackid,
FROM name,
table bytes
ORDER BY FROM
column_1 tracks
LIMIT row_count; ORDER BY
bytes DESC
LIMIT 10;
SQLite Limit과 Order By
Limit과 Order By를 이용하여 n번째 큰 값/작은 값을 구할 수 있다

1. 필드를 내림차순(n번째 큰 값을 구하는 경우) 또는 오름차순(n번째 작은 값을 구하는 경우) 정렬


2. Limit과 Offset을 이용하여 n번째 큰 값/작은 값을 구한다

명령 프롬프트 명령 프롬프트

SELECT 왼쪽 쿼리는 SELECT 왼쪽 쿼리는


trackid, trackid,
tracks테이블에서 tracks테이블에서
name, name,
milliseconds milliseconds값이 bytes 3번째로 bytes가 작은
FROM 2번째로 긴 트랙을 FROM 트랙을 구한다
tracks tracks
ORDER BY 구한다 ORDER BY
milliseconds DESC bytes
LIMIT 1 OFFSET 1; LIMIT 1 OFFSET 2;
SQLite Where
검색조건을 두고 조회하는 경우 WHERE를 사용한다. 자주 사용하는 구문중 하나이다.

명령 프롬프트
SQLite는 WHERE절이 있는 SELECT구문을 다음과 같이 해석한다
SELECT
column_list 1. FROM 뒤 테이블을 확인한다
FROM 2. WHERE절의 조건에 맞는 행을 구한다
table
3. SELECT에서 열거한 필드만 골라 최종 레코드셋을 만든다
WHERE
search_condition;
SQLite Where
WHERE절에서 가장 중요한 부분은 평가식을 만드는 것이다. 평가식은 다음과 같은 형식이다.

left_expression OPERATOR right_expression

왼쪽은 필드명, 오른쪽은 다른 필드명 또는 값이 온다. 그리고 operator는 비교/논리연산자이다.

WHERE Examples

WHERE column_1 = 100; column_1의 값이 100

WHERE column_2 IN (1,2,3); column_2의 값이 1,2,3중 하나

WHERE column_3 LIKE 'An%'; column_3의 값이 ‘An’으로 시작

WHERE column_4 BETWEEN 10 AND 20; column_4의 값이 10~20 사이


비교연산자
연산자 설명
= 같다

<> 또는 != 같지 않다

< 작다

> 크다

<= 작거나 같다

>= 크거나 같다
논리연산자
연산자 설명
AND 양쪽이 참이면

ANY 연산중 하나라도 1이면

BETWEEN 값이 범위내 있다면

EXISTS 서브쿼리에 행이 있으면

IN 값이 목록내 있다면

LIKE 값이 패턴과 일치하면

NOT 다른 연산 결과 반대

OR 평가식중 1이면 참
SQLite Where Example#1
아래와 같은 tracks 테이블이 있고, 필드중 Albumid=1 인 레코드를 검색하면

명령 프롬프트

SELECT
name,
milliseconds,
bytes,
albumid
FROM
tracks
WHERE
albumid = 1;
SQLite Where Example#2
Albumid=1이고 milliseconds > 250000 인 레코드를 검색한다면

명령 프롬프트

SELECT
name,
milliseconds,
bytes,
albumid
FROM
tracks
WHERE
albumid = 1
AND milliseconds > 250000;
SQLite Where Example#3

명령 프롬프트

SELECT
name,
albumid,
composer
FROM
tracks
WHERE
composer LIKE '%Smith%'
ORDER BY
albumid;
SQLite Where Example#4

명령 프롬프트

SELECT
name,
albumid,
mediatypeid
FROM
tracks
WHERE
mediatypeid IN (2, 3);
SQLite Where Example#5

명령 프롬프트

SELECT
trackid,
name,
mediatypeid
FROM
tracks
WHERE
mediatypeid IN (1, 2)
ORDER BY
name ASC;
SQLite Where Example#6

명령 프롬프트

SELECT
trackid,
name,
MediaTypeId
FROM
tracks
WHERE
mediatypeid = 1 OR
mediatypeid = 2
ORDER BY
name ASC;
SQLite In
IN 절은 목록내 값이 있는 지를 확인하는 조건절인데, 서브쿼리에 유용하다.

명령 프롬프트

SELECT
trackid, name, albumid
FROM
tracks
WHERE
albumid IN (
SELECT
albumid
FROM
albums
WHERE
artistid = 12 );
SQLite Not In
IN은 포함한 경우인데, 반대로 포함하지 않는 경우엔 NOT 연산자를 활용할 수 있다

명령 프롬프트

SELECT
trackid,
name,
genreid
FROM
tracks
WHERE
genreid NOT IN (1, 2, 3);
SQLite LIKE
정확하게 일치하는 것이 아니라 비슷한 형태 즉 패턴(전화번호, 우편번호 등등)에 맞는 문자열을 찾는 경우
LIKE 연산자를 사용한다 . LIKE는 WHERE절에 사용되며 DELETE/ UPDATE쿼리에도 사용한다.

명령 프롬프트 패턴에는 %와 _(언더스코어)를 사용한다. 이런 문자를


SELECT 와일드카드(wildcard) 라고 한다(대소문자 부분안함)
column_list
1. %는 0개 이상의 문자를 대신한다
FROM
table_name s% : s, son, so %er : er, peter, clever
WHERE %per% : per, percent, peeper
column_1 LIKE pattern;
2. _(언더스코어)는 한 개의 문자를 대신한다
h_nt : hunt, hint
__pple : topple, supple, tipple
SQLite Like
패턴은 기본적으로 대소문자를 구분하지 않는다. 대소문자를 구분하려면;

PRAGMA case_sensitive_like = true;

와일드카드가 아닌 문자로서 %와 _를 사용하고 싶다면, ESCAPE를 사용한다

column_1 LIKE pattern ESCAPE "escape_character";

아래 쿼리에서 %는 와일드카드이지만 _는 문자로서 사용하고 싶다면;

column_1 LIKE '%get_value%' ESCAPE '_';


SQLite Like Examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name LIKE 'Wild%'
SQLite Like Examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name LIKE '%Wild'
SQLite Like Examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name LIKE
'%Wild%';
SQLite Like Examples

명령 프롬프트

?
SELECT
trackid,
name
FROM
tracks
WHERE
name LIKE
'%Br_wn%';
SQLite GLOB
GLOB은 LIKE연산자와 비슷한 넘인데, LIKE와 달리 대소문자를 구분하고 Unix스타일의 패턴을 사용한다.
또한 ESCAPE 문자를 지원하지 않는다

명령 프롬프트 패턴에는 *, ? , [], ^ 를 사용할 수 있다.

SELECT 1. %는 0개 이상의 문자를 대신한다


column_list 2. ?는 한 개의 문자를 대신한다
FROM
3. []는 문자리스트중 하나를 대신한다
table_name
WHERE [x,y,z]은 하나의 문자 x, y, z
column_1 GLOB pattern;
[a-z]은 소문자 a부터 z까지
[a-zA-Z0-9]는 대소문자 알파벳과 숫자인 경우
4. ^ 는 ^다음의 문자로 시작하지 않는 경우
[^0-9]는 숫자로 시작하지 않는 경우
SQLite GLOB examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name GLOB 'Man*';
SQLite GLOB examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name GLOB '*Man';
SQLite GLOB examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name GLOB '?ere*';
SQLite GLOB examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name GLOB '*[1-9]*';
SQLite GLOB examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name GLOB '*[1-9]';
SQLite GLOB examples

명령 프롬프트

SELECT
trackid,
name
FROM
tracks
WHERE
name GLOB '*[^1-9]*';
SQLite Join
관계형 데이터베이스에선 자료를 여러 개의 테이블로 분산하고, Primary Key와 Foreign Key를 가지고
테이블간 관계를 만든다. 이를 JOIN이라고 한다
SQLite Inner Join
INNER JOIN은 테이블간의 교집합같은 공통분모만을 쿼리하는 것이다. 아래의 그림과 같이 두 개의 테이블
A와 B가 있는 데, 두 테이블간의 교집합을 쿼리하는 것이다. 구체적으로 A와 B는 f 공통의 필드를 가지고
있고 , f필드값이 서로 일치하는 레코드만 가져 오는 것이 INNER JOIN이다.
SQLite Inner Join Examples

SELECT
trackid,
name,
title
FROM
tracks
INNER JOIN albums ON albums.albumid = tracks.albumid;
SQLite Inner Join Examples

SELECT
trackid,
tracks.name AS Track,
albums.title AS Album,
artists.name AS Artist
FROM
tracks
INNER JOIN albums ON albums.albumid = tracks.albumid
INNER JOIN artists ON artists.artistid =
albums.artistid;
SQLite Inner Join Examples

SELECT
trackid,
tracks.name AS Track,
albums.title AS Album,
artists.name AS Artist
FROM
tracks
INNER JOIN albums ON albums.albumid = tracks.albumid
INNER JOIN artists ON artists.artistid = albums.artistid
WHERE
artists.artistid = 10;
SQLite Left Join
LEFT JOIN은 왼쪽 테이블 레코드와 테이블간의 공통분모를 쿼리하는 것이다. 아래의 그림과 같이 두 개의
테이블 A와 B가 있는 데, A와 B는 f 공통의 필드를 가지고 있고 , A의 f필드값에 해당하는 B의 레코드가
없어도 레코드를 가져 오는 것이 LEFT JOIN이다.
SQLite Left Join Examples
아래에는 artists와 albums 테이블이 있는 데, 앨범은 반드시 가수가 있을 테지만, 반대로 가수중에는 앨범이
없는 가수도 있을 것이다. 그래서 LEFT조인을 사용하여 앨범이 없는 가수를 찾아낼 수 도 있다.

SELECT
artists.ArtistId,
albumId
FROM
artists
LEFT JOIN albums ON albums.artistid = artists.artistid
WHERE
albumid IS NULL;
SQLite CROSS JOIN
매트릭스분석은 2×2, 3×3의 매트릭스(행,열)형태로 어떤
대상을 분석하는 것을 말한다. 우리가 너무마 잘 알고 있는 BCG
매트릭스도 이 분석의 일종이며, 포트폴리오 분석, IPA분석
(Importance-Performance Analysis),이라고 불려지는 분석들
또한 모두 매트릭스 분석이다. 이를 카테시안 곱(Cartesian
product), 데카르트곱 또는 곱집합이라고 한다.
SQL에선 JOIN, INNER JOIN, CROSS JOIN을 이용하여 이를
만들 수 있다.
SQLite CROSS JOIN
명령 프롬프트 테이블 A는 N개의 레코드가 있고, 테이블 B는 M개의 레코드가 있다고 하자.
SELECT * 이 두 테이블의 CROSS JOIN은 (N*M)개의 레코드를 만들어 낸다. 만일
FROM A JOIN B; K개의 레코드를 가진 테이블 C를 CROSS JOIN한다면 (N*M*K)개의
레코드를 만드는데, 엄청한 크기일 것이다.
SELECT *
FROM A
INNER JOIN B;

SELECT *
FROM A
CROSS JOIN B;

SELECT *
FROM A, B;
SQLite CROSS JOIN
명령 프롬프트

CREATE TABLE ranks (


rank TEXT NOT NULL);

CREATE TABLE suits (


suit TEXT NOT NULL);
왼쪽의 SQL를 실행하면 ranks와 suits

INSERT INTO ranks(rank) 테이블 두 개를 만들고 데이터를


VALUES('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9' 입력한다.
),('10'),('J'),('Q'),('K'),('A');

INSERT INTO suits(suit)


VALUES('Clubs'),('Diamonds'),('Hearts'),('Spades');
SQLite CROSS JOIN
명령 프롬프트 rank suits 왼쪽의 SQL를 실행하면 두 개의 테이블을
SELECT rank, 가지고 CROSS JOIN하여 두 개의 테이블 내용을
2 Clubs
suit 조합한 레코드셋을 만들 수 있다.
FROM ranks 3 Clubs
CROSS JOIN
suits 4 Clubs
ORDER BY suit; . ...

J Spades

Q Spades

K Spades

A Spades
SQLite FULL OUTER JOIN
FULL OUTER JOIN은 오른 쪽 그림과 같은 결과를 만든다.
이것은 LEFT JOIN과 RIGHT JOIN을 결합한 형태이다. 이
조인의 결과에는 일치하지 않는 행이 있으면 NULL값을
출력한다. 일치하는 행이 있는 경우 한 개의 행만 출력한다
SQLite FULL OUTER JOIN
명령 프롬프트 왼쪽의 SQL문은 dogs와 cats라는
-- create and insert data into the dogs table 테이블 두 개를 만들고, 몇 개의
CREATE TABLE dogs ( 레코드를 입력하는 것이다.
type TEXT, color TEXT);
INSERT INTO dogs(type, color)
VALUES('Hunting','Black'), ('Guard','Brown');

-- create and insert data into the cats table


CREATE TABLE cats (
type TEXT, color TEXT);

INSERT INTO cats(type,color)


VALUES('Indoor','White'), ('Outdoor','Black');
SQLite FULL OUTER JOIN
명령 프롬프트 Type Color Type Color
SELECT * Hunting Black Outdoor Black
FROM dogs
FULL OUTER JOIN cats Guard Brown NULL NULL
ON dogs.color = cats.color;
NULL NULL Indoor White

왼쪽의 SQL를 실행하면 두 개의 테이블을


가지고 FULL OUTER JOIN하여 두 개의 테이블
내용을 레코드셋을 합친 결과를 만들 수 있다.
SQLite Self-Join
Self-Join은 하나의 SQL문에서 한 개의 테이블을 명령 프롬프트

LEFT JOIN, INNER JOIN 절에 한 번 더 사용하는 SELECT a.ename , b.ename


것을 말한다. 이것은 하나의 데이터셋에 한 FROM emp a, emp b
WHERE a.mgr = b.empno;
테이블의 여러 행을 묶을 때 사용한다. 다음과 같은
형태가 Self-Join의 예이다.
SQLite Self-Join
오른 쪽의 employees에는 직원에 대한 정보와 조직에 대한 정보가 있다.
ReportsTo 컬럼은 직원간의 보고관계를 지정하고 있다. 여기에는 직원
자신이 보고해야 할 상급자의 EmployeeId가 들어가 있다.
가령 어느 사원 A가 어느 과장 B에게 보고하는 관계라면, 그 사원의
레코드중 ReportsTo컬럼에는 과장 B의 EmployeeId가 들어 가 있다.
누구에게도 보고할 대상이 없는 직원(직원중 최고 직위)의
ReportsTo컬럼에는 NULL이 들어간다.
SQLite Self-Join
누구에게 바로 보고해야 하는 지 알려면 아래과 같은 셀프조인 쿼리를 사용한다.

명령 프롬프트

SELECT m.firstname || ' ' || m.lastname AS 'Manager',


e.firstname || ' ' || e.lastname AS 'Direct report'
FROM employees e
INNER JOIN employees m ON m.employeeid = e.reportsto
ORDER BY manager;
SQLite Self-Join
앞의 쿼리에서는 INNER JOIN을 사용한 관계로 e.reportsto= NULL인 레코드가 출력되지 않아, 보고할 대상이
없는 직원(가령 사장님)의 기록은 나오질 않았다. 이 경우 INNER JOIN 대신 LEFT JOIN을 사용한다.

명령 프롬프트
SELECT m.firstname || ' ' || m.lastname AS 'Manager',
e.firstname || ' ' || e.lastname AS 'Direct report'
FROM employees e
LEFT JOIN employees m ON m.employeeid = e.reportsto
ORDER BY manager;
SQLite Self-Join
셀프조인 쿼리를 사용하여 같은 도시에 사는 직원들을 묶어 도시별로 출력할 수 있다

명령 프롬프트

SELECT DISTINCT
e1.city,
e1.firstName || ' ' || e1.lastname AS fullname
FROM
employees e1
INNER JOIN employees e2 ON e2.city = e1.city
AND (e1.firstname <> e2.firstname AND e1.lastname <> e2.lastname)
ORDER BY
e1.city;
SQLite Group By
GROUP BY절은 어느 행 그룹의 한 개 이상의 컬럼의 값을 가지고 요약된 행을 만드는 데 사용한다. 그래서
그룹을 요약하여 한 개의 행으로 나오게 하는 것이다. 요약하는 방법은 각각의 그룹에 대해 MIN, MAX,
SUM, COUNT, AVG와 같은 집계함수를 사용한다.

SELECT GROUP BY 절은 FROM 또는 WHERE가 있는 경우 그 다음에


column_1, 위치해야 한다.
aggregate_function (column_1)
FROM
table
GROUP BY
column_1, column_2, ...;
SQLite Group By
이번에는 tracks 테이블을 이용하여 GROUP BY를 알아본다. 가수의 앨범(album) 하나에는 여러개의 곡
(tracks)이 들어 가 있다. 각 앨범별 트랙 수를 조회해보자.

명령 프롬프트
SELECT
albumid,
COUNT(trackid)
FROM
tracks
GROUP BY
albumid;
SQLite Group By
ORDER BY절을 추가하여 트랙 갯수로 정렬할 수 있다.

명령 프롬프트
SELECT
albumid,
COUNT(trackid)
FROM
tracks
GROUP BY
albumid
ORDER BY COUNT(trackid) DESC;
SQLite Group By
이번에는 숫자로 나오는 Albumid 대신 앨범의 제목을 추가하여 표시해보자. 그러려면 앨범의 제목을 가진
albums 테이블을 조인해야 한다.

명령 프롬프트
SELECT
tracks.albumid,
title,
COUNT(trackid)
FROM
tracks
INNER JOIN albums ON albums.albumid
= tracks.albumid
GROUP BY
tracks.albumid;
SQLite Group By With Having
GROUP BY로 만든 그룹은 HAVING절을 이용하려 필터링할 수 있다. 예를 들어 15개 이상의 트랙을 가진
앨범으로 한정하여 쿼리를 한다면

명령 프롬프트
SELECT
tracks.albumid,
title,
COUNT(trackid)
FROM
tracks
INNER JOIN albums ON albums.albumid =
tracks.albumid
GROUP BY
tracks.albumid
HAVING COUNT(trackid) > 15;
SQLite Group By
이번에는 SUM()함수를 사용하여 각 앨범의 플레이시간 합계와 바이트수를 구해보자.

명령 프롬프트
SELECT
albumid,
sum(milliseconds) length,
sum(bytes) size
FROM
tracks
GROUP BY
albumid;
SQLite Group By
이번에는 여러 집계합수를 사용하여 앨범의 각 트랙중 플레이시간이 최소, 최대, 평균을 조회 해보자.

명령 프롬프트
SELECT
tracks.albumid,
title,
min(milliseconds),
max(milliseconds),
round(avg(milliseconds),2)
FROM
tracks
INNER JOIN albums ON albums.albumid = tracks.albumid
GROUP BY
tracks.albumid;
SQLite Group By
이번에는 두 개 이상의 컬럼으로 GROUP BY 하여 쿼리하는 예이다. tracks에는 MediaTypeId(파일형식),
GenreId(장르)가 있는 데, 저장된 파일형식으로 우선 묶고, 그안에서 장르로 다시 그룹짓는다.

명령 프롬프트
SELECT
mediatypeid,
genreid,
count(trackid)
FROM
tracks
GROUP BY
mediatypeid,
genreid;
SQLite Having
앞서 GROUP BY에서 HAVING을 잠깐 사용했는데, SELECT
HAVING은 그룹에 대한 필터링/검색을 의미한다. column_1,
대부분의 경우 HAVING은 단독으로 사용하지 않고 aggregate_function (column_2)
GROUP BY절과 함께 사용한다. GROUP BY없이 FROM
사용한다면 WHERE를 사용하는 것과 table
마찬가지이다. 즉 SELECT 쿼리 자체가 하나의 GROUP BY
그룹이기 때문이다. column_1
HAVING
search_condition;
SQLite Having
이번에는 tracks 테이블에서 albumid=1인 그룹의 트랙 갯수를 조회해보자

명령 프롬프트
SELECT
albumid,
COUNT(trackid)
FROM
tracks
GROUP BY
albumid
HAVING albumid = 1;
SQLite Having
이번에는 tracks 테이블에서 트랙 갯수가 18~20개인 앨범을 찾아보자

명령 프롬프트
SELECT
albumid,
COUNT(trackid)
FROM
tracks
GROUP BY
albumid
HAVING count(albumid) BETWEEN 18 AND 20
ORDER BY albumid;
SQLite Having
이번에는 albums 테이블과 조인하여 플레이 시간이 60,000,000 밀리세컨이상인 앨범을 조회해보자.

명령 프롬프트
SELECT
tracks.albumid,
title,
sum(Milliseconds) AS length
FROM
tracks
INNER JOIN albums ON albums.AlbumId
= tracks.AlbumId
GROUP BY
tracks.albumid
HAVING
length > 60000000;
SQLite CASE
CASE 는 쿼리에서 조건을 붙이기 위한 절이다.
명령 프롬프트
이것은 프로그래밍 언어의 IF-THEN-ELSE와
CASE case_expression
비슷하다. CASE는 WHERE, ORDER BY, WHEN when_expression_1 THEN result_1
HAVING, IN 와 같은 절과 SELECT, UPDATE, WHEN when_expression_2 THEN result_2
...
DELETE같은 구문에서 사용가능하다. 오른쪽
[ ELSE result_else ]
구문형식에서 END
case_expression=when_expression_1 이면
result_1을 돌려준다. 마찬가지로
case_expression=when_expression_2 이면
result_2을 돌려준다. 일치하는 것이 없다면
ELSE다음의 result_else를 돌려준다.
SQLite CASE
명령 프롬프트
SELECT
customerid, firstname, lastname,
CASE country
WHEN 'USA' THEN
'Dosmetic'
ELSE
'Foreign'
END CustomerGroup
FROM
customers
ORDER BY
LastName, FirstName;
SQLite CASE
명령 프롬프트
SELECT
trackid, name,
CASE
WHEN milliseconds < 60000 THEN
'short'
WHEN milliseconds > 6000 AND
milliseconds < 300000 THEN
'medium'
ELSE
'long'
END category
FROM
tracks;
SQLite Union
UNION은 두 개이상의 쿼리에서 나온 레코드를 query_1
합치는 쿼리이다. UNION은 중복된 레코드는 뺴고 UNION [ALL]
결과를 만들고, UNION ALL은 그 반대이다. query_2
UNION을 사용하기 위한 규칙 UNION [ALL]
1. 쿼리내 컬럼 갯수는 같아야 한다 query_3
2. 해당컬럼간에 데이터타입이 같아야 한다 ...;
3. 첫 쿼리의 컬럼이름이 결과 데이터셋 the difference between UNION and JOIN
컬럼이름이 된다 clause e.g., INNER JOIN or LEFT JOIN is that
4. 각각의 쿼리에 적용된 GROUP BY 와 the JOIN clause combines columns from
HAVING 절은 결과 데이터셋과 무관한다 multiple correlated tables, while UNION
5. 개별 결과데이터셋내에 사용하지 않은 combines rows from multiple similar tables.
ORDER BY 절은 결과 데이터셋에 적용된다
SQLite Union (ALL) Example

명령 프롬프트
SELECT
firstname,
lastname
FROM
employees
UNION ALL
SELECT
firstname,
lastname
FROM
employees;
SQL UNION with ORDER BY example
명령 프롬프트
SELECT
firstname,
lastname
FROM
employees
UNION
SELECT
firstname,
lastname
FROM
customers
ORDER BY
firstname,
lastname;
SQLite Subquery
Subquery는 SELECT문안에 SELECT문을 중첩하여 SELECT column_1
사용하는 쿼리이다. Subquery는 일종의 테이블이나 FROM table_1
조건절의 역할을 하며, 괄호안에 작성한다. WHERE column_1 = (
SELECT column_1
FROM table_2
);
SQLite subquery examples
서브쿼리는 “Let There Be Rock”
라는 제목을 가진 앨범의 id를
돌려주고, 이를 가지고
tracks테이블을 조회한다

명령 프롬프트
SELECT trackid, name, albumid FROM tracks
WHERE albumid = (
SELECT albumid
FROM albums
WHERE title = 'Let There Be Rock'
);
SQLite Insert
INSERT쿼리는 데이터를 테이블에 추가하는 쿼리이다. SQLite는 하나 이상의 레코드를 추가할 수 있다.

INSERT INTO table1 ( column1, column2 ,..) VALUES ( value1, value2 ,...);

● INSERT INTO 다음에는 테이블 이름이 온다.


● 그 뒤엔 컴마(,)로 분리한 필드이름 목록을 나열한다. 컬럼목록은 생략가능한데, 그런 경우 모든
컬럼을 지정한 것과 같다.
● VALUES 다음에는 컬럼목록의 순서대로 각 컬럼에 해당하는 값을 입력한다. 컬럼목록의 갯수와
VALUES 다음의 값목록 갯수는 같아야 한다.
● 컬럼중 자동증감하는 속성을 가진 컬럼(주로 ID로 사용하는 컬럼)은 생략해도 자동으로 입력된다.
SQLite Insert
Artists 테이블은 ArtistsId와 Name 두 개의 컬럼을 가지고 있다. 이 테이블에 새로운 가수이름 ‘Bud Powell’
을 추가하고 SELECT 쿼리를 하면

명령 프롬프트
INSERT INTO artists (name)
VALUES ('Bud Powell');
SELECT
artistid, name
FROM
artists
ORDER BY
artistid DESC
LIMIT 1;
SQLite INSERT – 여러 개의 레코드 추가
여러 개의 레코드를 추가하려면 VALUES 다음에 오는 값 목록을 여러 개 둔다.

INSERT INTO table1 ( 명령 프롬프트


column1, INSERT INTO artists (name)
column2 ,..) VALUES
VALUES ("Buddy Rich"),
( ("Candido"),
value1, ("Charlie Byrd");
value2 ,...), SELECT
( artistid,
value1, name
value2 ,...), FROM
... artists
( ORDER BY
value1, artistid DESC
value2 ,...); LIMIT 3;
SQLite Update
UPDATE쿼리는 기존의 데이터를 수정하는 쿼리이다.

UPDATE table 왼쪽의 SQL문은 UPDATE쿼리의 문법이다.


SET column_1 = new_value_1,
● UPDATE 다음에는 테이블 이름이 온다
column_2 = new_value_2
WHERE ● SET 다음에는 수정하려는 필드명과 새 값을 나열한다
search_condition ● WHERE 다음에는 업데이트할 레코드를 검색할 조건이다
ORDER BY column_or_expression ● ORDER BY, LIMIT, OFFSET은 업데이트할 레코드의
LIMIT row_count OFFSET
갯수를 지정한다.
offset;
● WHERE 이하의 조건절이 생략되면 모든 레코드의 필드가
업데이트된다
● ORDER BY SQLITE_ENABLE_UPDATE_DELETE_LIMIT
SQLite Update Example#1
다음은 employees 테이블을 대상으로 한 UPDATE쿼리 예이다.

명령 프롬프트 왼쪽의 쿼리는 emplopeeid=3인


UPDATE employees 직원의 성을 ‘Smith’로 변경하는
SET lastname = 'Smith'
예이다.
WHERE
employeeid = 3;
SQLite Update Example#2
다음은 여러 개의 필드를 업데이트하는 예이다.

명령 프롬프트
UPDATE employees
SET city = 'Toronto',
state = 'ON',
postalcode = 'M5P 2N7'
WHERE
employeeid = 4;
SQLite Update Example#3
함수를 사용하여 업데이트를 할 수도 있다. 다음은 lower()함수를 사용하여 이메일을 업데이트하는 예이다

명령 프롬프트
UPDATE employees
SET email = lower(
firstname || "." || lastname || "@chinookcorp.com"
);
SQLite Studio
a SQLite database manager
데이터베이스와 테이블 만들기
a collection of data
데이터베이스 만들기

● [File ]-[New database] 또는 [New Database] 클릭한다(Ctrl + N)


● 대화상자에서 디비파일을 저장할 위치와 파일이름을 입력
주식 종가 테이블 설계(스키마)
일자별 주식종가를 담을 수 있는 테이블을 설계하고 데이터를 추가하기

● 테이블 이름과 필드명 : 영문으로 작성


● 필드 데이터 타입 :
Integer, Text, BLOB, Real, Numeric
● Primary Key : 다른 레코드와 구별되는 필드
● Not Null : 데이터의 존재유무
● AutoIncrement : 자동증감
● Unique : 중복되지 않는 데이터 유무
● 기본값 : 자동으로 입력되어 있는 데이터
CSV파일로 테이블 만들거나 채우기
[가져오기]-[CSV파일에
서 테이블 가져오기]를
클릭하여
1)새로운 테이블을
만들거나
2)기존테이블에
데이터를 채울 수 있다
ODBC 설정
ODBC(Open DataBase Connectivity)는
마이크로소프트가 만든, 데이터베이스에 접근하기
위한 소프트웨어의 표준 규격으로,
각 데이터베이스의 차이는 ODBC 드라이버에
흡수되기 때문에 사용자는 ODBC에 정해진 순서에
따라서 프로그램을 쓰면 접속처의 데이터베이스가
어떠한 데이터베이스 관리 시스템에 관리되고
있는지 의식할 필요 없이 접근할 수 있다.

1. 설정에서 ODBC를 검색
2. ODBC 데이터 원본 설정(32비트) 선택
ODBC 설정
1. [시스템 DSN] 탭으로 이동
2. [추가] 클릭
엑셀에서 ODBC 연결하기
ODBC 설정
1. [새 데이터 원본 만들기]의 드라이버 목록중
“SQLite3 ODBC Driver” 선
ODBC 설정
1. [SQLite3 ODBC DSN Configuration]에서
[Data Source Name] 에 연결할 DSN이름 입력
2. [Database Name]에서 앞서 만든 db파일을
선택
엑셀에서 ODBC 연결하기
엑셀에서 ODBC 연결하기
엑셀에서 ODBC 연결하기
엑셀에서 ODBC 연결하기
엑셀에서 ODBC 연결하기
엑셀의 데이터베이스 관련 기능
Formulas and functions related to database
데이터베이스 함수
데이터베이스에 저장된 데이터를 분석하는 함수를 데이터베이스 함수라고 하는데, 이러한 함수들은
데이터베이스, 필드, 조건의 세 개의 인수를 사용합니다.

● DSUM(Database, Field, Criteria) : 지정한 조건에 맞는 필드 값들의 합계


● DCOUNT(Database, Field, Criteria) : 지정한 조건에 맞는 숫자가 들어 있는 셀의 개수
● DMAX(Database, Field, Criteria) : 지정한 조건에 맞는 필드의 값 중에서 가장 큰 값
○ - Database : 셀 범위
○ - Field : 함수에서 사용할 열을 지정하는 것으로 필드명
즉 "나이" 또는 "수확량"처럼 열 레이블을 큰 따옴표로 묶은 텍스트로 Field 인수를 지정할 수도 있으며,
첫째 필드에 1, 둘째 필드에 2와 같은 순서로 된 필드 번호로 Field 인수를 지정할 수도 있습니다.
○ - Criteria : 찾을 조건이 들어 있는 셀 범위
데이터베이스 함수
함수명 기능

DAVERAGE 조건에 맞는 값들의 평균을 구함


DCOUNT 조건에 맞는 값들의 개수를 구함
DCOUNTA 조건에 맞는 값들의 비어있지 않은 셀의 개수를 구함

DGET 조건에 맞는 값을 구함
DMAX 조건에 맞는 값들 중 최대값을 구함
DMIN 조건에 맞는 값들 중 최소값을 구함
DPRODUCT 조건에 맞는 값들의 곱을 구함
DSTDEV 조건에 맞는 값들의 표본 표준편차를 구함
DSTDEVP 조건에 맞는 값들의 모집단 표준편차을 구함
DSUM 조건에 맞는 값들의 합을 구함
DVAR 조건에 맞는 값들의 표본 분산을 구함
DVARP 조건에 맞는 값들의 모집단 분산을 구함
표 기능
엑셀의 표기능은 목록의 형태를 띤 데이터를 처리할 수 있는 뛰어난 툴을 제공한다. 이러한 데이터의 집합을
‘테이블’, 각 테이블의 열 제목을 ‘필드’, 각각의 데이터를 ‘레코드’라고 부른다.

제목 열과 열을 포함하여 데이터를 선택하고 [삽입] - [표] 를 클릭한다. 선택한 영역이 정확한지 눈으로
확인하고 머리글 포함 체크상자를 클릭한 후 확인 을 클릭한다. 그러면 양식을 갖춘 표가 생성된다.
표 기능 - 다양한 서식지원
엑셀은 표로 지정되는 순간 데이터 영역을 다른 데이터 들과
구분하기 위해 기본적인 디자인이 적용된다. 이 디자인은 꽤나
스타일리쉬 한 것이 많으며 한번의 버튼 클릭만으로 화려한 표를
디자인 할 수 있다.
기본으로 적용된 스타일이 싫다면 수 많은 스타일 중에서 하나
고르거나 아니면 스타일을 없앤 후 자신이 수동으로 지정 해도 된다.

그러나 디자인은 나중에 내용을 다 완성하고 하는 것이 시간을


절약한다.
표 기능 - 필터링
표로 되는 순간 표의 모든 필드(첫번째 행)에는 필터
화살표가 생겨서 데이터의 필터, 검색 등을 할 수 있다.

엑셀의 표 기능을 일부 사용하고 싶지만 데이터를


분류하거나 정렬하지 않을 경우, 필터의 화살표를 감출 수
있다.

이를 위해서는 표 내부의 한 곳을 클릭하고 [데이터] -


[정렬 및 필터] - [필터]를 선택한다(Shift-Ctrl-L)
표 기능 - 표에서 정상범위로 돌아가기
데이터를 엑셀의 표로 작성하는 것은 엑셀에서 깔끔한 형태의 셀을 구성하는 가장 손쉬운 방법이다. 유일한
단점은 표에 원하는 기능만을 적용하여 구성할 수 없을 것 같아 보인다는 것이다.

다시 원래의 입력한 스타일(행과 열주소를 갖고 수식을 입력하던 형태)로 돌아가려면

1) 표의 안쪽을 클릭하고
2) [디자인] - [범위로 변환] 을 클릭한다.
3)'표를 정상 범위로 변환하시겠습니까?'라는 메시지가 표시될 때 예를 클릭하면
4)표가 양식은 유지된 채 정상 범위로 복귀된다.
표 기능 - 표에 새로운 행 추가하기
표에서 행은 일반적인 작업시트의 행과는 조금 다르다. 표에 새로운 행을 추가해야 할 경우 1) 표의 우측 하단
셀을 클릭하고 2) Tab 키를 누른다.
표 기능 - 요약 행
일부 행이 숨겨져 있어도 합계 함수는 범위 내에 있는 모든
셀의 합계를 계산한다. 보이는 행의 수를 합한 값을 결과를
표시하지 않는다. 이런 문제를 해결하기 위해서는
SUBTOTAL을 사용한다. 표의 경우 자동이다.

표에 합계 행을 추가하려면
1)표의 내부를 마우스로 우 클릭한 후 [표] - [요약행] 선택
2)[디자인] - [요약행]을 클릭

요약행에서 드롭다운(Drop-down)를 클릭하면 최소값,


최대값, 숫자 개수, 평균 등의 기타 계산 옵션을 선택할 수
있다.
표기능 - 표 데이터에서 차트 생성하기
목록을 표로 구성했을 때의 장점은 표
데이터로부터 생성한 차트가 표에서 데이터를
추가하거나 삭제할 때 능동적으로 변화한다는
점이다.
따라서 어떤 범위의 값으로 구성된 열 차트는 표에
새롭게 추가된 값을 포함하기 위해 확장된다.
표의 아래쪽에 새로운 데이터를 추가하거나 우측에
새로운 열을 추가할 때도 같은 현상이 발생한다.
표기능 - 슬라이서
자동필터를 통해서 슬라이서와 같은 기능을 구현할 수 있지만 슬라이서를 사용하는게 훨씬 빠르고 직관적이다.
자주 사용하는 필터항목은 슬라이서를 하나 장만해두는 것이 좋다.
표 기능 - 수식
표는 데이터베이스처럼 활용 할 수 있다.
수식을 넣을 때 엑셀 시트의 위치 정보를 일일이 기억 하는 것 보다
사람이 이해하기 쉬운 필드 이름으로 넣는 것이 훨씬 더 편리
데이터를 레코드 즉 행 단위로 기억하며 같은 행에 있는 것은 같은 레코드 즉 같은 데이터 단위이다. 그래서
새로운 열을 생성해서 수식을 입력하면 모든 행에 같은 수식이 자동 적용된다.

● 지급액합계 = SUM(급여명세표[@[기본급여]:[기타수당]])
● 공제액계 = SUM(급여명세표[@[건강보험]:[기타공제]])
● 실급여지급액 =[@지급액합계]-[@공제액계]
SQL
SQL(Structured Query Language)
관계형 데이터베이스 관리 시스템(RDBMS)의
데이터를 관리하기 위해 설계된 특수 목적의
프로그래밍 언어이다
SQL(structured query language)
SQL[시퀄 또는 에스 큐 엘]은 데이터베이스에서 정보를 얻거나 갱신하기 위한 표준화된 언어로서
대화형으로 이용하거나, 또는 프로그램 내에 삽입하여 쓸 수 있다. SQL이 ANSI와 ISO의 표준이긴 하지만
표준으로 정해진 사항에 덧붙여, 독자적인 확장 SQL을 지원하는 데이터베이스도 많다.

SQL은 크게 데이터와 그 구조를 정의하는 DDL(Data Definition Language)와 데이터의 검색과 수정을 위한
DML(Data Manipulation Language) 그리고 데이터베이스 사용자의 권한을 정의하는 DCL(Data Control
Language)의 세 가지로 분류할 수 있다.
기본적인 SQL
데이터베이스 프로그래밍을 하기 위해서 가장 먼저 배우는 것이 쿼리(Query)이다. 이것은 업계 표준이어서
모든 데이터베이스 시스템은 이를 사용하여 데이터베이스를 조작할 수 있도록 하고 있다. 그러나 모든
데이터베이스 제품들이 표준을 지키는 것은 아니다. 성능향상, 기존제품과의 호환성 등등의 이유로 나름의
쿼리를 만들어 제품에 적용하고 있다. 따라서 제품에 따라 쿼리가 조금씩 다를 수 있다. 그러나 기본적인
쿼리는 모두 같으므로 안심하고 사용해도 좋다.

쿼리는 하나의 프로그래밍 언어에 속하는 데, 간단히 다음의 4가지 정도의 쿼리만 익히면 프로그래밍에 큰
어려움은 없으리라 생각한다. 데이터베이스를 조작하는 일이란 데이터베이스로부터원하는 데이터를
출하는 일(SELECT 쿼리), 데이터베이스에 데이터를 입력하는 일(INSERT 쿼리), 입력한 데이터를 수정하는
일(UPDATE 쿼리) 그리고 필요없는 데이터를 데이터베이스에서 삭제하는 일(DELETE 쿼리)이다.
SELECT 쿼리
Select쿼리(‘선택쿼리’라고 함)는 한 개이상의 테이블에서 필요한 데이터를 가져오는 구문이다. 가장 많이
사용하는 쿼리인 만큼 익숙해지면 편리하다. 엑셀의 워크시트에서 데이터를 필터링
(자동필터/고급필터기능)하여 원하는 데이터만 추리는 것에 해당하는 구문이다.

SELECT [DISTINCT|ALL] <LIST OF COLUMNS, FUNCTIONS, CONSTANTS,ETC.>


FROM <LIST OF TABLES OR VIEWS>
[WHERE <CONDITION(S)>]
[GROUP BY <GROUPING COLUMN(S)>]
[HAVING <CONDITION>]
[ORDER BY <ORDERING COLUMN(S)> [ASC|DESC]];
ORDER BY 절
Order By절은 Select쿼리에서 레코드를 정렬하는 방법을 지정하는 것이다. Order By 다음에는 필드이름을
입력하는데, 기본적으로 오름차순으로 정렬된다. 그리고 내림차순으로 정렬하려면 ‘DESC’를 필드이름
다음에 입력한다.

‘Orders’ 테이블에서 Company필드를 오름차순으로 정렬한다면 다음과 같이 쿼리를 만든다.

● SELECT Company, OrderNumber FROM Orders ORDER BY Company


● SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC, OrderNumber ASC
WHERE 조건절
모든 데이터를 가져오지 않고 특정조건을 만족하는 데이터만 가져오려면 조건절을 사용해야 한다. 조건절은
SELECT쿼리 뿐만 아니라 이후에 설명할 INSERT쿼리, UPDATE쿼리, DELETE쿼리 등등에서 사용할 수 있다.
WHERE조건절에서 사용할 수 있는 연산자는 다음과 같다.

1. 비교연산자 : =, <>, >, <, >=, <=, BETWEEN, LIKE


2. 논리연산자 : AND/ OR

● SELECT * FROM Persons WHERE City='Sandnes'


● SELECT * FROM Persons WHERE FirstName LIKE '%la%
● SELECT * FROM Persons WHERE FirstName='Tove' AND LastName='Svendson'
INSERT 쿼리
Insert쿼리는 테이블에 데이터를 입력하는 쿼리이다. Insert쿼리는 다음과 같은 형식으로 사용한다.

INSERT INTO <TABLE NAME> [(<COLUMN LIST>)] VALUES (<VALUE LIST>);


UPDATE 쿼리
Update쿼리는 기존에 입력된 데이터를 변경할 때 사용한다. Update쿼리는 다음과 같은 형식으로 사용한다,

UPDATE <TABLE NAME> SET <COLUMN NAME> = <VALUE> [WHERE <CONDITION>];


DELETE 쿼리
Delete쿼리는 테이블에서 레코드를 삭제하는 쿼리이다. 필드를 삭제하는 것이 아니다. Delete쿼리는 다음과
같은 형식으로 사용한다.

DELETE FROM <TABLE NAME> WHERE <CONDITION>;


SQL함수
SQL에서는 필드이름이나 값을 매개변수로 하여 함수를 사용할 수 있다. 산업표준(SQL-92)에서 정의한
함수는 몇 개의 기본적인 것이다. 그러나 대부분의 RDBMS제품에는 제작사가 표준규격을 확장하여 여러
가지 함수를 독자적으로 제공하고 있다.
● COUNT() - 쿼리의 결과로 반환된 행(레코드)의 갯수를 반환한다.
● SUM() - 필드의 합계를 돌려준다.
● AVG() - 필드의 평균값을 계산한다.
● MAX() - 필드의 레코드에서 가장 큰 값을 반환한다.
● MIN() - 지정한 필드의 레코드중 가장 작은 값을 반환한다.
[실습] W3SCHOOLS
W3schools은 웹과 관련한 기초적인 웹개발
정보를 제공하는 사이트인데, 웹개발을 위한
여러 프로그래밍 언어를 알려준다. 기초적인
HTML/CSS부터 자바스크립트, PHP, SQL
강의자료를 공부할 수 있으며, 온라인상으로
HTML/CSS, JAVASCRIPT, SQL 실습도 할 수
있다.

https://www.w3schools.com/sql/default.asp
SQLite Python
Python을 사용하여 SQLite 데이터베이스를
어떻게 다루는 지 알아봅니다
SQLite Python
SQLite와 관련하여 인기있는 파이썬 라이브러리에는 PySQLite와 APSW가 있습니다.

● PySQLite - PySQLite는 Python DBI API 2.0 과 호환되는 SQLite 인터페이스를 제공한다. SQLite

뿐만 아니라 다른 데이터베이스 가령 MySQL, PostgreSQL, Oracle 등을 고려한다면 PySQLite는 좋은

선택이다. PySQLite는 Python2.5 이후 표준 라이브러리가 되었다.

● APSW -SQLite만 사용한다면 Python SQLite Wrapper인 APSW 모듈은 사용할 수 있다. APSW 는

SQLite 데이터베이스 라이브러리에 가벼운 인터페이스를 제공한다. APSW는 SQLite C를 모방한

것이다. 그래서 SQLite C API를 사용하는 것이라면 얼마든지 Python으로 할 수 있다.


SQLite Python: Querying Data
데이터를 가져 오려면 다음과 같은 몇 가지 단계가 필요하다.

1. Connection개체를 만들어 SQLite데이터베이스에 대한 연결을 만든다

2. Connection개체를 이용하여 Cursor개체를 만든다

3. Cursor개체를 이용하여 SELECT 쿼리를 실행한다

4. Cursor개체의 fetchall() 메서드를 이용하여 데이터를 가져온다

5. Cursor개체를 루프돌면서 각 행을 처리한다


SQLite Python: Querying Data
import sqlite3 def select_all_tasks(conn):
from sqlite3 import Error cur = conn.cursor()
cur.execute("SELECT * FROM tasks")
def create_connection(db_file):
try: rows = cur.fetchall()
conn = sqlite3.connect(db_file)
return conn for row in rows:
except Error as e: print(row)
print(e)

return None
SQLite Python: Querying Data
def select_task_by_priority(conn, priority): def main():
cur = conn.cursor() database = "C:\\sqlite\db\pythonsqlite.db"
cur.execute("SELECT * FROM tasks WHERE conn = create_connection(database)
priority=?", (priority,)) with conn:
print("1. Query task by priority:")
rows = cur.fetchall() select_task_by_priority(conn,1)

for row in rows: print("2. Query all tasks")


print(row) select_all_tasks(conn)

if __name__ == '__main__':
main()
SQLite Python: Inserting Data
데이터를 추가하려면 다음과 같은 몇 가지 단계가 필요하다

1. Connection개체를 만들어 SQLite데이터베이스에 대한 연결을 만든다

2. Connection개체를 이용하여 Cursor개체를 만든다

3. Cursor개체의 execute()메서드를 사용하여 INSERT 쿼리를 실행한다

4. 쿼리에서 입력하려는 데이터 위치에는 각각 매칭되는 플레이스홀더(?)를 둔다


SQLite Python: Inserting Data
아래와 같은 일대다의 관계를 가진 projects테이블과 tasks 테이블이 있을 때, 두 테이블에 데이터를

추가하는 쿼리를 해보자


SQLite Python: Inserting Data
def create_project(conn, project):
"""
Create a new project into the projects table
:param conn:
:param project:
:return: project id
"""
sql = ''' INSERT INTO projects(name,begin_date,end_date) VALUES(?,?,?)
'''
cur = conn.cursor()
cur.execute(sql, project)
return cur.lastrowid
SQLite Python: Inserting Data
def create_task(conn, task):
"""
Create a new task
:param conn:
:param task:
:return:
"""
sql = ''' INSERT INTO
tasks(name,priority,status_id,project_id,begin_date,end_date)
VALUES(?,?,?,?,?,?) '''
cur = conn.cursor()
cur.execute(sql, task)
return cur.lastrowid
SQLite Python: Inserting Data
def main():
database = "C:\\sqlite\db\pythonsqlite.db"
conn = create_connection(database)
with conn:
project = ('Cool App with SQLite & Python', '2015-01-01', '2015-01-30');
project_id = create_project(conn, project)
# tasks
task_1 = ('Analyze the requirements of the app', 1, 1, project_id,
'2015-01-01', '2015-01-02')
task_2 = ('Confirm with user about the top requirements', 1, 1,
project_id, '2015-01-03', '2015-01-05')
# create tasks
create_task(conn, task_1)
create_task(conn, task_2)
SQLite Python: Inserting Data

if __name__ == '__main__':
main()
SQLite Python: Updating Data
데이터를 업데이트하려면 다음과 같은 몇 가지 단계가 필요하다

1. Connection개체를 만들어 SQLite데이터베이스에 대한 연결을 만든다

2. Connection개체를 이용하여 Cursor개체를 만든다

3. Cursor개체의 execute()메서드를 사용하여 UPDATE 쿼리를 실행한다

4. 쿼리에서 필요한 데이터 위치에는 각각 매칭되는 플레이스홀더(?)를 둔다


SQLite Python: Updating Data
def update_task(conn, task):
"""
update priority, begin_date, and end date of a task
:param conn:
:param task:
:return: project id
"""
sql = ''' UPDATE tasks SET priority = ?, begin_date = ?, end_date = ?
WHERE id = ?'''
cur = conn.cursor()
cur.execute(sql, task)
SQLite Python: Updating Data
def main():
database = "C:\\sqlite\db\pythonsqlite.db"

# create a database connection


conn = create_connection(database)
with conn:
update_task(conn, (2, '2015-01-04', '2015-01-06',2))

if __name__ == '__main__':
main()
SQLite Python: Deleting Data
데이터를 삭제하려면 다음과 같은 몇 가지 단계가 필요하다

1. Connection개체를 만들어 SQLite데이터베이스에 대한 연결을 만든다

2. Connection개체를 이용하여 Cursor개체를 만든다

3. Cursor개체의 execute()메서드를 사용하여 DELETE 쿼리를 실행한다

4. 쿼리에서 필요한 데이터 위치에는 각각 매칭되는 플레이스홀더(?)를 둔다


SQLite Python: Deleting Data
def delete_task(conn, id):
"""
Delete a task by task id
:param conn: Connection to the SQLite database
:param id: id of the task
:return:
"""
sql = 'DELETE FROM tasks WHERE id=?'
cur = conn.cursor()
cur.execute(sql, (id,))
SQLite Python: Deleting Data
def delete_all_tasks(conn):
"""
Delete all rows in the tasks table
:param conn: Connection to the SQLite database
:return:
"""
sql = 'DELETE FROM tasks'
cur = conn.cursor()
cur.execute(sql)
SQLite Python: Deleting Data
def main():
database = "C:\\sqlite\db\pythonsqlite.db"

# create a database connection


conn = create_connection(database)
with conn:
delete_task(conn, 2);
#delete_all_tasks(conn);

if __name__ == '__main__':
main()

You might also like