SELECT
WHERE
ORDER BY

SELECT 문의 구문



  SELECT문은 네 개의 DML문 중에서 가장 많이 쓰이는 구문입니다. 그리고 UPDATE, INSERT, DELETE 문 내에서 서브쿼리로써 존재할 수 있습니다. SELECT 문은 최소한 다음의 두 요소로 구성됩니다.

     SELECT LIST : 검색될 열의 LIST
     FROM 구 : 행을 검색하기 위한 TABLE

 그럼 간단한 예를 보죠. 다음은 student란 Table에서 이름(name)을 검색하는 쿼리입니다.

     SELECT name FROM student ;

 결과는 다음과 같이 나오겠죠.
    NAME
  ----------
    김정민
    정완교
    박범길
    유현승
     ……

  학생의 이름과 나이를 알고싶으면 희망하는 순서로 열을 나열하면 됩니다.

     SELECT name, age FROM student ;

  결과는 다음과 같이 나옵니다.
    NAME      age
 ---------- ---
     김정민      27
     정완교      28
     이해준      26
     최종혁      27
     박범길      24

테이블의 모든 열을 검색하려면 *을 사용하면 됩니다.

     SELECT * FROM student ;
NAME AGE ENG_SCORE KOR_SCORE ... AVR_SCORE
---------------------------------...----------
정완교 28 90 85 ... 93
이해준 26 70 90 ... 80
최종혁 27 30 10 ... 20
박범길 24 100 100 ... 100
최선재 23 90 90 ... 90
조관현 28 85 100 ... 87.5
... ... ... ... ... ...
김정민 27 0 10 ... 5

 
모든 SELECT 문에 의해서 복귀된 결과는 임시 테이블을 구성합니다. 각 검색된 레코드는 이 임시 테이블 내에서 하나의 행이고 선택 리스트의 각 요소는 하나의 열입니다. 만약 쿼리가 어떠한 레코드도 복귀시키지 않는다면 임시 테이블은 빈 것으로 생각할 수 있죠.
그리고 위에서 열을 지정한 것처럼 선택 리스트 네에서 표현식을 지정할 수 있습니다. 표현식은 열과 동일한 데이터타입 (문자, 수치, 날짜)에 속합니다. 여러분은 연산자, 내장함수, 그리고 상수를 이용하여 여러분의 APPLICATION의 필요를 만족시킬 수 있는 복잡한 표현식도 작성할 수 있습니다.
그리고 표현식이 다수의 열을 참조할 지라도 MySQL이 선택 리스트 내에 있는 각 요소를 독립된 열로 간주한다는 것을 기억하세요.
SQL에서 사용되는 산술 연산자는 C 언어에서 사용되는 산술 연산자와 동일합니다. 더하기(+), 빼기(-), 곱하기(*), 나누기(/)... 모두 똑 같습니다.
다음은 학생들의 영어 성적과 국어 성적을 평균내는 것입니다.
 
SELECT name, eng_score, kor_score, (eng_score+kor_score)/2 FROM student ;
 
NAME ENG_SCORE KOR_SCORE (ENG_SCORE+KOR_SCORE)/2
---------- ------------ ------------- -----------------------
정완교 90 85 87.5
이해준 70 90 80
최종혁 30 10 20
박범길 100 100 100
최선재 90 90 90
조관현 85 100 87.5
... ... ... ...
김정민 0 10 5

SQL에서 사용되는 문자열 연산자(String Operator) 중 가장 중요한 것이 연결 연산자(Concatenation Operator) 입니다. 이 연산자는 둘 이상의 문자열을 함께 연결할 수 있게 합니다.
 
     SELECT name || ', ' || city FROM student ;
 
     NAME||','||CITY
   ----------------
     정완교, 부산
     이해준, 진주
     최종혁, 서울
     박범길, 수원
     최선재, 수원
     조관현, 서울
      ...
     김정민, 부산

어떤 경우에 문자열을 연결할까요?


여러분은 두 개 이상의 문자열로 연결 연산자를 사용할 수 있습니다. ', '는 문자열을 콤마(,)와 공백으로 연결할 수 있도록 사용된 것입니다.
 

WHERE


SQL은 레코드를 검색하는데 이용할 수 있는 기준을 지정하는 WHERE 구를 제공합니다. 어떤 테이블이 많은 행을 가지고 있을 경우, 그 행들을 모두 검색하면 참 불편하겠죠? WHERE 구는 쿼리에 의해 검색되는 행을 위해서 만족되어야 하는 한 개 이상의 조건문으로 구성되어 있습니다.
 
만약 여러분이 서울에 사는 학생들의 List만 원한다면 아래와 같이 할 수 있겠죠.

SELECT name, eng_score, kor_score FROM student WHERE city='서울' ;
NAME ENG_SCORE KOR_SCORE
---------- ----------- ----------
조관현 85 100
최종혁 30 10

 
WHERE문을 사용할 때 AND 와 OR 키워드로 조건문을 조합할 수도 있습니다.
서울이나 수원에 살고 영어 성적이 80점 이상인 학생만 보는 예를 들어보죠.

SELECT * FROM student WHERE city='서울' OR city='수원' AND eng_score>=80 ;
NAME AGE ENG_SCORE KOR_SCORE ... AVR_SCORE
---------------------------------...----------
박범길 24 100 100 ... 100
최선재 23 90 90 ... 90
조관현 28 85 100 ... 87.5

ORDER BY


그럼 데이터를 소트(Sort)시켜서 쿼리하는 법을 볼까요? 여러분은 ORDER BY구를 이용해서 쿼리되는 데이터를 소트시킬 수 있습니다. ORDER BY 구는 쿼리가 복귀시키는 행의 순서를 매기는데 사용되어야 하는 열을 지정하는데 사용됩니다.
SELECT name, age FROM student ORDER BY name ;
NAME AGE
---------- ---
김정민 27
박범길 24
이해준 26
정완교 28
조관현 28
최선재 23
최종혁 27

순서를 정리할 때 MySQL의 경우는 아무런 옵션이 없을 경우, 행을 오름차순(ASC)으로 순서를 정합니다. 열의 순서를 내림차순으로 정리하려면 열의 이름 뒤에 DESC 키워드를 추가해야 합니다.
SELECT name, age FROM student ORDER BY name DESC ;
NAME AGE
---------- ---
최종혁 27
최선재 23
조관현 28
정완교 28
이해준 26
박범길 24
김정민 27

그런데 가끔은 내가 찾고자 하는 데이터나 행이 얼마나 되는지 알고 싶을 때가 있죠? 그때는 COUNT라는 함수를 사용합니다. COUNT 함수는 지정된 기준을 만족시키는 행의 수를 복귀시킵니다.
SELECT count(*) FROM student WHERE eng_score>=80 ;
COUNT(*)
--------
4

그러면 서브쿼리는 어떻게 사용하는지 볼까요? 서브쿼리는 다른 DML(SELECT, UPDATE, DELETE, INSERT) 문으로 정의됩니다. 만약에 영어성적에 대해서 전체 평균보다 점수가 낮은 학생을 조회하고 싶다면 다음과 같이 사용하면 됩니다. avg()는 ORALCE이 제공하는 평균을 내는 함수죠.
SELECT name, eng_score FROM student WHERE eng_score < (SELECT avg(eng_score) FROM student) ;
서브쿼리를 사용할 경우, 다음의 내용을 주의하세요.
서브쿼리는 괄호로 묶어야 한다.
서브쿼리에 의해서 복귀된 행의 수는 함수 또는 연산자가 기대하는 값의 수와 일치해야 한다.
ORDER BY 구는 서브쿼리 문에서 사용할 수 없다.
 
또 SELECT 문으로 새로운 테이블을 만들 수도 있어요. 다음과 같이 CREAT TABLE 문과 SELECT 문을 함께 사용하면 됩니다. WHERE 문을 주어서 원하는 조건만으로 테이블을 만들 수도 있겠죠.
CREATE TABLE new_table_name AS select_statement ;
CREATE TABLE eng_score_table AS SELECT name, age, eng_score FROM student ;
여러분은 선택 리스트 내에서 복잡한 표현문을 지정할 때 그것에게 앨이어스를 할당함으로써 결과값의 문서를 보기 좋게 할 수 있습니다. 다음 두 가지 예를 볼까요?
SELECT name, eng_score, kor_score, (eng_score+kor_score)/2 FROM student ;  
NAME ENG_SCORE KOR_SCORE (ENG_SCORE+KOR_SCORE)/2
---------- ------------ ------------- -----------------------
정완교 90 85 87.5
이해준 70 90 80
최종혁 30 10 20
박범길 100 100 100
최선재 90 90 90
조관현 85 100 87.5
... ... ... ...
김정민 0 10 5

SELECT name, eng_score, kor_score, (eng_score+kor_score)/2 AVERAGE FROM student ;  
NAME ENG_SCORE KOR_SCORE AVERAGE
---------- ------------ ------------- -----------------------
정완교 90 85 87.5
이해준 70 90 80
최종혁 30 10 20
박범길 100 100 100
최선재 90 90 90
조관현 85 100 87.5
... ... ... ...
김정민 0 10 5

첫 번째 예와 두 번째 예를 비교해보면 두 번째 예가 훨씬 깔끔하죠? 이것을 표현식 (eng_score+kor_score)/2에 앨리어스 AVERAGE를 할당한다고 하며, 여기서 두가지 이익을 얻을 수 있습니다.
표현식을 정확히 기술하는 이름을 갖는다.
ORDER BY 구 내에서 앨이어스를 참조할 수 있다.
 
관계형 데이터베이스 시스템(RDBMS) 기술과 비관계형 데이터베이스 시스템(DBMS) 기술 사이의 한 가지 주요 차이점은 널(Null) 값의 개념입니다. 비관계형 데이터베이스 시스템에서, 어떤 문자 또는 수치 필드에 어떤 값이 없다는 것은 어떤 특별한 값에 의해서 표시됩니다.
관계형 데이터베이스에서는 어떤 열을 위한 널(Null) 값은 다양한 이유로 나타납니다.
이 열을 위한 값은 문제의 행에 적용되지 않는다. 이 열은 아직 값을 할당받지 못했다.
그럼 열 값으로 널(Null)을 갖고 있는 행을 찾아볼까요?
SELECT name, eng_score, kor_score FROM student WHERE phone_no is Null;
NAME ENG_SCORE KOR_SCORE
---------- --------- ----------
이해준 70 90
최종혁 30 10
... ... ...
김정민 0 10

어떤 값이 Null인 이유를 이해하는 것이 중요합니다. 전화번호와 같은 것은 Null이
될 수도 있죠. 왜냐하면
효일이는 자취하고, 원희는 새로 이사했는데 전화를 놓지 않았고, 교락이는 집에서
쫓겨났기 때문에.. 후후..
그냥 WHERE 절을 이용해서 Null 값을 찾을 수 있다는 것만 기억하세요.
그리고 NOT 연산자를 이용해서 Null이 아닌 행을 검색할 수도 있습니다. 예를
들어서 전화번호를 메모한 학생들의 전화번호를 알고 싶으면 다음과 같이 하면 되지요.
SELECT name, eng_score, kor_score FROM student WHERE phone_no is Not Null;
NAMEENG_SCOREKOR_SCORE
---------- --------- ----------
정완교 90 85
박범길 100 100
최선재 90 90
조관현 85 100
... ... ...

그럼 이제 연산자에 대해서 간단히 알아봅시다. 연산자에는 LIKE, BETWEEN, IN 등의 연산자가 있어요.
LIKE 연산자는 찾아내고자 하는 항목을 위한 정확한 철자를 모를 때 테이블을 검색하는데 이용하게 됩니다.
문법은 다음과 같아요.
SELECT name, eng_score FROM student WHERE name like '%혁%' ;
NAME ENG_SCORE
---------- ---------
최종혁 30

BETWEEN 연산자는 AND 와 함께 사용되어 연결되는 두 개의 조건문과 같이 작용합니다.
SELECT name, eng_score FROM student WHERE eng_name BETWEEN 85 AND 95 ;
위의 문장은 아래의 문장과 동일한 문장입니다.
SELECT name, eng_score FROM student WHERE eng_score >= 85 AND eng_score <= 95 ;
NAME ENG_SCORE
---------- ---------
박범길 100
최선재 90
조관현 85

마지막으로 이제 IN 연산자에 대해 알아보죠. IN 연산자는 열 또는 표현식의 값을 가능한 값들의 리스트를 비교하는데 사용됩니다. 그리고 IN 연산자는 Boolean 값을 복귀시키죠.
표현식이 표현식 리스트에 있는 모든 값 중 하나와 같으면 TRUE 표현식이 표현식 리스트에 있는 모든 값 중 같은게 없으면 FALSE
SELECT name FROM student WHERE city IN ('Suwon', 'Seoul') ;
NAME
----------
박범길
최선재
조관현

위의 내용과 반대의 내용이 나타나도록 NOT 키워드를 사용할 수도 있죠.
SELECT name FROM student WHERE city NOT IN ('Suwon', 'Seoul') ;
NAME AGE
---------- ---
김정민 28
정완교 29
이해준 26
최종혁 50
.......