![]() Manuel Soriano Contents: 들어 가는 말 Table 만들기 Table 수정하기 Table에 데이타 입력하기 데이타 선택하기 WHERE에 대한 자세한 설명 UPDATE 명령 DELETE 명령 참조 |
SQL Tutorial
|
name: | 생성될 table의 이름이다. |
Column: | 컬럼의 이름이다. |
Type: | 데이타의 타입이다.(varchar, char, int, date, time, timestamp), Postgres 는 다른 data type도 있지만, ANSI SQL과는 호환되지 않는다. |
Value: | default로 가질 값을 지정한다. |
Inherits: | Postgre에만 있는 것으로, 다른 테이블에 있는 모든 컬럼을 상속받게 된다. |
Nom_cons: | row가 수정될 때마다 데이타의 값이 정당한지를 정의한다. |
Test: | 검사할 조건이다. |
CREATE TABLE countries ( cod_country integer NOT NULL, name varchar(30)) CONSTRAINT cod_raro CHECK (cod_country > 0 AND cod_country < 154);
위의 예에서 countries라는 table을 만들었다. 테이블에 값을 입력할 때마다 다음 조건에 맞는지 확인하게 된다.
ExecAppend: cod_country의 속성이 NULL이 아니기 때문에 실패하게 된다.
ExecAppend: cod_raro 검사를 거부하게 된다.
NULL은 무엇을 의미하는가? SQL에는 data와 data가 아닌 것 두가지 상태가 있다. 영(0)이나 공백 문자 데이타를 의미하는 것처럼 우리는 데이타를 가지지 않는 필드를 필요로 할 때가 있다. SQL에서는 NULL이라는 개념을 도입했다. 실제적인 예는 다음과 같다.
bill이라는 데이블을 만들고, customer, value, date_issued, date_paid라는 필드를 가지고 있다.
그리고 customer, value, date_issued 필드에 값을 대입하고,
date_paid는 NULL로 했다. 이런 식으로 지불해야할 돈을 알수가 있다.
SELECT * FROM bills WHERE date_paid IS NULL ;
date_padi를 영(0)으로 해도 값은 효과를 낼 수 있다고 생각하는 사람도 있을 텐데, 영(0)이 날짜가 아닌 것을 제외하고, 맞는 말이다. 그리고 날짜에 관한 함수를 이용하고, date type의 date_paid를 만드는 것을 방지한다.
(역자주 : 영어가 짧아서 번역이 엉성하군여 ^^; 원문입니다.
One can claim that a zero (0) in the field date_paid would do the same thing. It's
true,
except that zero (0) is not a date, and it prevents creating date_paid of date type
and
applying appropriate date functions.)
NULL을 이용하여 생성하는 예:
insert into countries values (15, NULL);또는:
insert into countries (cod_country) values (27);
'name'에 값을 대입하지 않는 것은 NULL 값을 받는 다는 것을 의미한다.
PostgreSQL에서는 Table의 수정은 새로운 컬럼을 추가하는 일만을 할 수 있다.
ALTER TABLE table ADD name type;
Table | 수정하고자 하는 Table의 이름 |
Name | 추가하고자 하는 컬럼의 이름 |
Type | data의 타입 ( CREATE TABLE을 보라) |
이제 Table에 값을 입력하는 것에 대해 배운다.
문법:INSERT INTO table [(column, column, ...)] VALUES (value-1, value-2, ...)or else:
INSERT INTO table [(column, column, ...)] SELECT ....
보았다 시피 table에 데이타를 입력하는 방법은 두 가지가 있다. 한줄 한줄 입력하는 방법과 여러 row를 리턴하는 sub-select를 이용하는 방법이다.
table에 데이타를 입력할 때는 NULL 값을 포함한 모든 컬럼들에 값을 집어 넣어야 한다.
데이타를 입력하는 명령에 어떤 컬럼에 값을 입력할지 명시화하지 않으면 모든 컬럼에 데이타를 입력하는 것으로 이해한다. 예를 들어:
INSERT INTO countries VALUES (34, 'Spain');다음은 틀린 것이다.
INSERT INTO countries VALUES (34);하지만 다음은 옳은 것이다.
INSERT INTO countries (cod_country) VALUES (34);
필자는 C 언어에서 DB 프로그래밍을 하거나 database 함수를 사용할 때 원하는 컬럼을 꼭 명시화 할 것을 추천하는 바이다. 왜냐하면 ALTER TABLE등을 이용하여 새로운 컬럼을 추가했을 때 다음 번의 insert는 에러를 내기 때문이다.
예:
이는 'population' data가 빠졌기 때문에 구문 에러를 내게 된다.
PostgreSQL에서는 에러를 발생하지 않고, 'population' 필드를 NULL로 채운다. 하지만, 이것은 PostgreSQL의 특징이고, 다른 SQL에서는 에러를 발생할 것이다.
sub-select를 이용한 다른 방법의 INSERT가 있다.
이 방법의 insert는 임시적인 table을 만들거나 위험을 내포한 계산을 안전하게 하기 위해서 자주 쓰인다.
insert를 이용해서 data가 자체가 대치된 경우, 이것은 SELECT에 의해서 반환된다. SELECT는 한 row 또는 여러 row를 리턴할 수 있다. SELECT는 SELECT와 같은 제약 사항을 가진다.
필자는 빨리 이 부분으로 오길 원했다.! :-))
SQL 명령을 몇 가지 보았느데, SELECT없는 SQL 언어는 순대에 불과하다.
SELECT 명령은 우리가 data에 접근하는 것을 허락한다. 하지만 이러한 접근은 예약된 것들, 즉 탐색이나, table들의 결합, data에 관한 함수, 탐색 규약 등이다.
예:
select * from countries;
*는 모든 컬럼을 의미한다.
다른 예:
SELECT a.name, SUM(population) FROM countries a, states b, counties c WHERE b.cod_country = a.cod_country AND (c.cod_country = b.cod_country AND c.state_code = b.state_code) AND population IS NOT NULL GROUP BY a.name ORDER BY sum ASC;
설명상, 필자는 모든 나라의 인구를 올림차순으로 보길 원했다.
이를 위하여 'population'이라는 컬럼을 counties table에 추가했다.
다음과 같다:create table counties (cod_country int, state_code int, county_code int, county_name varchar(60), population int); insert into counties values (1, 1, 1, 'Country 1, State 1, County 1', 5435); insert into counties values (2, 1, 1, 'Country 2, State 1, County 1', 7832); insert into counties values (3, 1, 1, 'Country 3, State 1, County 1', 4129); insert into counties values (1, 2, 1, 'Country 1, State 2, County 1', 76529); insert into counties values (2, 2, 1, 'Country 2, State 2, County 1', 9782); insert into counties values (3, 2, 1, 'Country 3, State 2, County 1', 852); insert into counties values (1, 3, 1, 'Country 1, State 3, County 1', 3433); insert into counties values (2, 3, 1, 'Country 2, State 3, County 1', 7622); insert into counties values (3, 3, 1, 'Country 3, State 3, County 1', 2798); insert into counties values (1, 1, 2, 'Country 1, State 1, County 2', 7789); insert into counties values (2, 1, 2, 'Country 2, State 1, County 2', 76511); insert into counties values (3, 1, 2, 'Country 3, State 1, County 2', 98); insert into counties values (1, 2, 2, 'Country 1, State 2, County 2', 123865); insert into counties values (2, 2, 2, 'Country 2, State 2, County 2', 886633); insert into counties values (3, 2, 2, 'Country 3, State 2, County 2', 982345); insert into counties values (1, 3, 2, 'Country 1, State 3, County 2', 22344); insert into counties values (2, 3, 2, 'Country 2, State 3, County 2', 179); insert into counties values (3, 3, 2, 'Country 3, State 3, County 2', 196813); insert into counties values (1, 1, 3, 'Country 1, State 1, County 3', 491301); insert into counties values (2, 1, 3, 'Country 2, State 1, County 3', 166540); insert into counties values (3, 1, 3, 'Country 3, State 1, County 3', 165132); insert into counties values (1, 2, 3, 'Country 1, State 2, County 3', 0640); insert into counties values (2, 2, 3, 'Country 2, State 2, County 3', 65120); insert into counties values (3, 2, 3, 'Country 3, State 2, County 3', 1651462); insert into counties values (1, 3, 3, 'Country 1, State 3, County 3', 60650); insert into counties values (2, 3, 3, 'Country 2, State 3, County 3', 651986); insert into counties values (3, 3, 3, 'Country 3, State 3, County 3', NULL); commit work;
이제 우리는 ALTER TABLE를 이용할 수 없지만, 아직 설명하지 않은 UPDATE를 사용할 수 있다. "cut & paste"를 이용하라. 모든 사람이 happy 해질 것이다. :-))
쿼리를 수행함으로서 다음과 같은 결과를 얻을 수 있다.
name | sum - ---------+------- country 1| 705559 country 2|1212418 country 3|2804018 (3 rows)다음과 같이 하면:
sum - ------ 791986 (1 row)
!!!!!! 하나가 다르다 !!!!!!
이제 states table을 보자. state 3를 빼억었다.
INSERT INTO states VALUES (3, 1, 'State 3, Country 1'); INSERT INTO states VALUES (3, 2, 'State 3, Country 2'); INSERT INTO states VALUES (3, 3, 'State 3, Country 3');그리고 명령을 반복하여 다음과 같은 결과를 얻는다.
name | sum - ---------+------- country 1| 791986 country 2|1872205 country 3|3003629
각각의 country에 state 3가 없다.
(테이블 간의 joindl EXACT임을 기억하라) 없어진 것들에 대해서 조건에 맞는 것들만 추출할 수 있다.
다시 윗 부분으로 올라가서WHERE b.cod_country = a.cod_country부분을 보자.
이것은 country table과 state를 cod_country가 같은 것을 join했다는 것을 말해준다. country data가 사입됐다는 것을 기억해라.
다음을 실행시키지는 마라. 단순한 예이다.
create table countries (cod_country integer, name varchar(30)); insert into countries values (1, 'country 1'); insert into countries values (2, 'country 2'); insert into countries values (3, 'country 3'); commit work;이제 states data를 보자
create table states (state_code int, cod_country int, state_name varchar(30)); insert into states values (1, 1, 'State 1, Country 1'); insert into states values (2, 1, 'State 2, Country 1'); insert into states values (1, 2, 'State 1, Country 2'); insert into states values (2, 2, 'State 2, Country 2'); insert into states values (1, 3, 'State 1, Country 3'); insert into states values (2, 3, 'State 2, Country 3'); commit work;각각의 country에 대해서 state 3가 없다. 그러나, country table에는 states 3가 있다. 따라서, 우리가 where의 두 번째 부분에서 code 3를 무시하고, country data에 states를 추가하지 않은 것은 당연한 것이다.
AND (c.cod_country = b.cod_country AND c.state_code = b.state_code)
state는 counties table에는 있지만, states table에는 없다.
위에서 말한 것이 이해가 잘 안 간다면, 아스피린 한 알을 먹고, 개와 함께 산책을 나가라(개가 없으면 혼자 가라). 심호흡을 좀 하면서 쉰 후에 처음부터 다시 시작하라
Join을 한 결과가 어떻게 나오는지 이해하는 것은 매우 중요하다. 이러한 개발을 하지 않는다면, 예측할 수 없는 결과가 나올 수 있다.
이제 관점을 조금 바꿔서 SELECT 명령의 문법에 대해서 알아 보자
SELECT [DISTINCT] expression1 [AS nom-attribute] {, expression-i [as nom-attribute-i]} [INTO TABLE classname] [FROM from-list] [WHERE where-clause] [GROUP BY attr_name1 {, attr_name-i....}] [ORDER BY attr_name1 [ASC | DESC ] [USING op1 ] {, nom-attribute-i...}] [UNION {ALL} SELECT ...]하나씩 살펴보자
DISTINCT: | row가 중복되어 리턴되는 것을 막는다. |
expression1: | 우리가 리턴되기 원하는 것이다. 보통 FROM 뒤에 오는 Table의 컬럼이 된다. |
AS nom-attribute: | 컬럼 이름의 별명(alias)이다.예를 들어:
manu=> select cod_country from countries; cod_country - ----------- 1 2 3 (3 rows)별명(alias)를 이용하면: manu=> select cod_country as countr from countries; countr - ------ 1 2 3 (3 rows) |
INTO TABLE: | 결과가 다른 Table로 직접 삽입 되게 한다. ( INSERT ... SELECT...를 보라) |
FROM: | Table들의 목록이다. |
WHERE: | 선택 문, selection statement (union 과 selection criteria). |
GROUP BY: | group criteria, 특정한 그룹화하는 함수가 쓰인다. |
ORDER BY: | 리턴되는 row의 순서를 정한다. ASC:오름 차순, DESC:내림 차순, USING:(expression) 목록에 순서가 정의되어 있지 않을 때. |
UNION ALL SELECT: | This says to add to the results of the first SELECT this second SELECT that can be different tables, but return the same number of columns. |
SELECT 명령은 DB로부터 아이템을 리턴하는 것 뿐만아니라, item을 수정할 수도 있다는 것을 보았다.
이것은 지불의 10%를 리턴한다.
사용가능한 함수들에 대해서 알아 보자:
COUNT(): | NULL이 아닌 row의 수를 리턴한다. |
SUM(): | 컬럼들의 합을 리턴한다. |
AVG(): | 컬럼들의 평균을 리턴한다. |
MIN(): | 컬럼에서 가장 작은 값을 리턴한다. |
MAX(): | 컬럼에서 가장 큰 값을 리턴한다. |
FLOAT(int): | 정수를 실수로 리턴한다.,FLOAT(12345) |
FLOAT4(int): | 정수를 실수로 리턴한다.FLOAT4(12345) |
INT(float): | 실수를 정수로 리턴한다.,INT(123.456) |
LOWER(text): | text를 소문자로 리턴한다. |
UPPER(text): | text를 대문자로 리턴한다. |
LPAD(text, long, char): | text의 왼쪽부터 long만큼의 길이까지 char로 채운다. |
RPAD(text, long, char): | text의 오른쪽부터 long 만큼의 길이를 char로 채운다. |
LTRIM(text, char): | text의 왼쪽부터 text안의 모든 char를 지운다. |
RTRIM(text, char): | text의 오른쪽부터 text안의 모든 char를 지운다. |
POSITION(string IN text): | string안에서 text의 위치를 추출한다. 하지만, 이것은 작동하지 않는다. |
SUBSTR(text,from[,to]): | text의 from위치부터 to까지, 혹은 스트링의 마지막까지(to가 생략되었다면) 문자를 추출한다. |
DATETIME(date, hour): | datetime의 형식을 date (YYYY-MM-DD) 와 hour (HH:MM) 형식으로 바꾼다. |
이것들은 SQL에 있는 몇가지의 함수들이다. 이들 함수는 ANSI SQL에 정의되어 있고, Postgres95에도 정의되어 있다.
지금까지 SELECT에서의 WHERE에 대해 보았고, 다음과 같이 쓰일 수 있다.
AND column = value
간단한 예일뿐이고, 다음과 같이 쓰거나, 아니면 함께 묶어서 쓸 수 있다.
AND, OR, NOT, IN, IN ALL, =, !=, >, <, (SELECT....), LIKE 등도 또한 쓰일 수 있다. 예:
WHERE column IN (SELECT DISTINCT column FROM table WHERE ....) column IN ('value1','value2','value3',...) (column = 'value' and column = 'other_value' OR column != 'value')!= '같지 않음'을 나타낸다.
WHERE column LIKE '%Pepito%'%는 wildcard이다. 예를 들어 "Pepito"가 문자열에 안에 있으면 참이다.
WHERE column LIKE 'Pepito%'"Pepito"가 문자열의 시작이면 참이다.
WHERE column LIKE '%Pepito'이는 "Pepito"가 문자열의 끝이면 참이다.
WHERE와 함께 쓰일 수 있는 모든 옵션들을 열거할만한 시간이 없다. 한계는 프로그래머의 상상력이나, 각각의 문장 작업의 한계에 있다. 이제 SELECT 명령은 그만하고, 마지막 두가지에 대해서 집중을 하자
UPDATE 명령은 WHERE에 있는 조건들을 만족하는, 한 row 혹은 여러 row의 값을 수정할 수 있다.
SYNTAX:UPDATE table SET column-1 = expression-1 [, column-i = expression-i] [WHERE condition]Where:
table: | 수정하고자 하는 Table이다. 한번에 하나의 Table만이 수정될 수 있다. |
column: | 수정되고자 하는 컬럼이다. |
expression: | 컬럼이 수정되어질 값이다. 이 값은 정적이거나, 혹은 함수로부터 나온 결과 값일 수 있다. |
condition: | SELECT에 의해 주어진 수정되어질 조건들이다. |
DELETE FROM table [WHERE condition]
table: | 삭제될 row가 있는 Table의 이름이다. 한번에 하나의 Table만이 지워질 수 있다. |
condition: | SELECT에 의해서 주어진 지워질 조건들이다. NOTE: WHERE을 안 쓰면 Table의 모든 row들이 삭제될 것이다.
|
번역:허정수
영문으로 번역: Dallas L. Gale
본 웹싸이트는 Miguel Ángel Sepúlveda씨에 의해 관리됩니다. © Manuel Soriano 1998 LinuxFocus 1998 |