1. GROUP BY

 

🍋 기준이 되는 필드를 뒤에 적어주면 기준 필드가 같은 레코드를 모아 통계값을 구함

🍋 GROUP BY 구문은 그룹핑을 해 줄 뿐이며 어떤 통계를 낼 것인가는 필드 목록의 집계 함수에 따라 달라짐

🍋 여러 개의 집계함수를 동시에 사용 가능

SELECT '영업부', AVG(salary) FROM tStaff WHERE depart='영업부';
SELECT '총무부', AVG(salary) FROM tStaff WHERE depart='총무부';
SELECT '인사과', AVG(salary) FROM tStaff WHERE depart='인사과';
 

📌  부서별 월급 평균을 알고 싶어 부서마다 AVG 함수를 호출하게 되면 부서 목록을 만들고 각 부서마다 명령을 일일이 실행해야 하고 결과도 따로 출력되어 보기도 불편하다. 또한, 집계함수와 일반필드를 같이 적을 수 없어 필드 목록에 부서명을 한 번 더 적어야 한다.

 

💡 이 경우에 필요한 구문이 GROUP BY. 기준 필드는 집계 함수와 같이 쓸 수 있어서 목록도 보기 좋게 출력 할 수 있음.

 

 

📌  부서별 월급 평균을 구하려면 depart 필드 기준으로 그룹핑

    1)  기준 필드순으로 정렬하여 같은 그룹끼리 구분

    2)  통계 대상 필드를 순서대로 읽어 집계를 구함

SELECT depart, AVG(salary) FROM tStaff GROUP BY depart;
SELECT grade, AVG(salary) FROM tStaff GROUP BY grade;
SELECT depart, COUNT(*), MAX(joindate), AVG(score) FROM tStaff GROUP BY depart;
 

 

 

 

2. 기준 필드

 

🍋 GROUP BY의 기준 필드는 중복 값이 있을 때만 의미있다.

     ➡️ 레코드별로 고유한 값을 가지는 필드는 그룹핑 기준으로 부적합(예 : 아이디)

     ➡️ 한 부서에서 여러 직원이 소속되어 있고 부서가 같은 직원이 많기 때문에 부서별 집계 가능.

     ➡️ 성별도 중복값이어서 그룹핑 필드로 적합

SELECT gender, AVG(salary) FROM tStaff GROUP BY gender;
 

 

 

📌  남녀 성별로 평균 월급을 구함. 성별은 남자, 여자 두 부류이며 그룹핑한 결과도 2개의 레코드로 출력

 

 

 


 

 

🔖  중복 값을 가지는 필드만 그룹핑의 기준이 되는 것은 아니며 임의의 필드를 기준으로 그룹핑 할 수 있다.

SELECT name, SUM(salary) FROM tStaff GROUP BY name;
 

 

 

 

 

 

📌 이름을 기준으로 그룹핑을 하는 것도 문법적으로 가능하지만 전 직원의 월급이 각각 출력이 되어 의미가 없음.

 

 

 

 

 

 

 


 

🔖  기준 필드를 콤마로 구분하여 두 개 이상도 쓸 수 있다.

      ➡️ 이 경우 첫 번째 기준으로 그룹을 나누고 그 그룹 내에서 다시 두 번째 기준으로 그룹을 나눈다.

🔖  기준 필드의 순서는 그룹핑 과정에 영향을 주지만 결과에는 영향을 미치지 않는다.

      ➡️ 순서는 ORDER BY로 조정 가능

SELECT depart, gender, COUNT(*) FROM tStaff GROUP BY depart, gender;
SELECT gender, depart, COUNT(*) FROM tStaff GROUP BY gender, depart;
SELECT depart, gender, COUNT(*) FROM tStaff GROUP BY depart, gender ORDER BY gender, depart;
 

 

📌 부서별, 성별로 그룹핑하여 직원수 구함.  총무부는 여직원이 없어서 5개의 그룹만 나옴.

 

 

 

3.  GROUP BY의 필드 목록

 

⚡️  <그룹핑 쿼리의 기본 형식>

SELECT 기준필드, 집계함수() FROM 테이블 GROUP BY 기준필드;
 

🍋 GROUP BY 절이 있으면 필드 목록에는 기준 필드나 집계 함수만 와야 한다.

🍋 필드 목록의 제일 처음에는 통상 기준 필드를 출력하여 어떤 그룹에 대한 통계인지 표시

      ➡️ 기준 필드를 빼고 집계 함수만으로 쿼리를 구성하면, 계산은 똑바로 됐지만 각 행이 어떤 부서에 대한 통계치인지 알아 볼 수 없다.

 

SELECT depart, salary FROM tStaff GROUP BY depart;
SELECT SUM (salary) FROM tStaff GROUP BY depart;
 

 

 

 

🍋  집계 함수는 다중 값이 있어야 계산할 수 있으므로 그룹핑을 할 때만 유용

       ➡️ GROUP BY 절 없이 일반 필드와 집계 함수를 같이 출력하면 의미가 없다

SELECT depart, SUM(salary) FROM tStaff;
 

  📌  레코드별로 고유한 부서명과 통계에 의해 계산하는 월급 총합은 같이 출력할 수 있는 값이 아니라서

        이 명령은 다음 둘 중에 하나로 수정하는게 적당.

 📌  뒤에 GROUP BY 절을 붙여 부서별로 그룹핑하면 기준 필드인 부서명도 출력할 수 있고

       부서의 월급 총합을 구하는 SUM 함수도 사용할 수 있다.

SELECT depart, SUM(salary) FROM tStaff GROUP BY depart;
SELECT SUM(salary) FROM tStaff;
 

 

 

 

4. HAVING

 

// 위치 순서
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY
 

🍋 HAVING은 GROUP BY 다음에 오며 통계 결과 중 출력할 그룹의 조건을 지정 (즉 HAVING은 GROUP BY 문의 조건절)

 

  📌  부서별 평균 월급을 출력하는 명령은 별다른 조건이 없으면 모든 부서의 평균 월급을 출력.

        평균 월급이 340을 넘는 부서만 출력하고 싶다면 GROUP BY 다음에 HAVIING 절을 추가.

SELECT depart, AVG(salary) FROM tStaff GROUP BY depart HAVING AVG(salary) >= 340;
 

 

📌  그룹별 통계를 뽑고 그 결과셋에서 HAVING 조건에 맞는 레코드만 출력.

      평균 월급이 327인 인사과는 제외.

 

 

 


 

 

🍋 출력 순서를 지정할 때는 ORDER BY 절을 뒤에 붙인다.

🍋 GROUP BY 다음에 HAVING이 오고 ORDER BY는 항상 제일 마지막에 위치한다.

SELECT depart, AVG(salary) FROM tStaff 
  GROUP BY depart HAVING AVG(salary) >= 340 
    ORDER BY AVG(salary) DESC;
 

 


 

 

🍋 WHERE 와 HAVING은 적용 시점과 제한 대상이 다르다.

🍋 WHERE 절은 GROUP BY 앞에 나타나며 통계 대상 레코드의 조건을 제한한다.

SELECT depart, AVG(salary) FROM tStaff WHERE salary > 300 GROUP BY depart;
 

 

 

📌  월급 300 초과 조건에 의해 월급 300 이하의 직원은 평균에서 아예 제외되어 평균값이 더 높게 나타남. 만약 모든 직원의 월급이 300 이하이면 이 부서는 아예 결과셋에 나타나지고 않음.

 

 

 

 

🍋 HAVING 절은 GROUP BY 다음에 나타나며 집계한 결과셋의 조건을 제한한다.

SELECT depart, AVG(salary) FROM tStaff WHERE salary > 300 GROUP BY depart 
HAVING AVG(salary) >= 360 ORDER BY depart;
 

 

 

📌 월급이 300 초과인 직원들을 대상으로 부서별 평균 월급을 구하고 그 결과 평균 월급이 360 이상인 부서만 고른 후 부서명으로 정렬

 

 

⚡️ 처리순서

 

1. WHERE 절이 직원목록에서 월급 300이하의 직원을 먼저 제거

2. 부서별로 그룹핑하여 AVG 함수로 남은 직원의 부서별 평균 월급을 계산

3. HAVING 절에 의해 평균 월급이 낮은 부서는 제외

4. 남은 부서를 ORDER BY가 정렬하여 출력

 

 

 

SELECT depart, MAX(salary) FROM tStaff WHERE depart IN ('인사과', '영업부') GROUP BY depart;
SELECT depart, MAX(salary) FROM tStaff GROUP BY depart HAVING depart IN ('인사과', '영업부');
 

 

 

📌 두 쿼리 모두 인사과와 영업부의 최대 월급을 조사.

📌 조건을 적용하는 시점은 다르지만 조건의 내용은 같아 최종 실행 결과는 같음.

 

 

💡 내부적인 실행 과정은 차이가 있음

    1. WHERE 절은 집계전에 총무부를 제외하여 꼭 필요한 계산만 함.

    2. HAVING 절은 모든 부서의 집계를 다 끝낸 후 총무부를 제거하는 식이라 출력하지도 않을 총무부의 집계까지 계산하여 비효율적

 

 

 

 

 

 

[ 내용 참고 ; IT 학원 강의 ]

 

 


 

1. 집계함수 Aggregate Function

🍋  집계 함수는 복수개의 레코드에 대해 집합적인 계산을 수행하여 합계, 평균, 분산 같은 통계값을 산출.

🍋  테이블에 저장된 정보를 함수로 전달하면 원본 데이터를 변형, 가공하여 돌려준다.

🍋  함수 호출문이 하나의 값이므로 필드 목록이나 조건절등에 값처럼 사용하면 된다.

함수명
설명
COUNT()
행의 개수를 센다
AVG()
평균을 구한다
MIN()
최소값을 구한다
MAX()
최대값을 구한다
STDEV()
표준편차를 구한다
VAR_SAMP()
분산을 구한다

 


 

(1) COUNT() : 행의 개수를 센다

📍 COUNT는 개수를 조사할 필드명을 전달하는데 * 지정하면 필드에 상관없이 조건에 맞는 레코드 개수를 리턴

 

// tStaff 테이블에 저장되어 있는 레코드 개수
  SELECT COUNT(*) FROM tStaff;
// 계산값은 열 이름이 없는데 별명을 부여하면 결과셋에 이름을 표시.
  SELECT COUNT(*) AS "총 직원수" FROM tStaff;

 

 

 

 

📍 WHERE 절을 붙이면 조건에 맞는 레코드의 개수를 구한다.

SELECT COUNT(*) FROM tStaff WHERE salary >= 400; // 월급이 400 이상인 직원의 수
SELECT COUNT(*) FROM tStaff WHERE salary >= 10000; // 월급이 10000 이상인 직원의 수

 

📍 집계는 모든 레코드의 값을 참고하여 하나의 값을 구하는 것이어서 결과셋은 목록이 아닌 딱 하나의 값

       ➡️ 집계하는 말 자체가 다중값으로 부터 단일 값을 산출한다는 의미.

📍 조건에 맞는 레코드가 없어도 결과 값은 역시 하나

 

 

📍 특정 필드의 개수를 구할때는 인수로 필드명을 적는다.

      ➡️ 지정한 필드 값이 존재하는 레코드의 개수를 구함

SELECT COUNT(name) FROM tStaff; 
SELECT COUNT(depart) FROM tStaff;

 

 

 

 

📍 중복 부서를 제외하고 부서의 종류가 몇 개인지 알고 싶으면 필드명 앞에 DISTINCT 키워드를 붙인다.

SELECT COUNT(DISTINCT depart) FROM tStaff;

 

 


 

📍 COUNT 함수는 '필드값이 제대로 들어 있는 레코드의 개수만 구하며' 필드값이 NULL인 레코드는 개수에서 제외.

📍 name이나 depart는 NULL이 없어 전체 직원수와 같지만, score 필드는 NULL 값이 있음.

SELECT COUNT(score) FROM tStaff; 
SELECT COUNT(*) - COUNT(score) FROM tStaff; 
SELECT COUNT(*) FROM tStaff WHERE score IS NULL;

 

 

 

 

(2) SUM(), AVG(), MIN(), MAX()

 

SELECT SUM(popu), AVG(popu) FROM tCity; // 도시 목록에서 인구의 총합과 평균을 구함. 
SELECT MIN(area), MAX(area) FROM tCity; // 모든 도시의 area 필드를 조사하여 가장 작은 값과 가장 큰 값을 찾음.

 

 

 

 

 

📍 WHERE 절을 붙이면 조건을 만족하는 레코드에 대해서만 집계를 함

 

SELECT SUM(score), AVG(score) FROM tStaff WHERE depart = '인사과'; // 인사과의 총 실적 합계과 평균
SELECT MIN(salary), MAX(salary) FROM tStaff WHERE depart = '영업부'; // 영업부에서 가장 낮는 월급과 가장 높은 월급

 

 

 

 

📍 문자열끼리는 더할 수 없어 총합을 계산할 수 없고 평균도 의미가 없다.

📍 but! 문자열이나 날짜끼리는 사전순으로 비교할 수 있고, 날짜에 대해서는 MIN, MAX 함수 사용 가능하다.

📍 집계함수와 일반필드은 같이 사용하면 안된다.

SELECT SUM(name) FROM tStaff; 
SELECT MIN(name) FROM tStaff; 
SELECT MAX(popu), name FROM tCity; (x) 
-> SELECT popu, name FROM tCity ORDER BY popu DESC LIMIT 1;

 

 

 

(3) 집계 함수와 NULL

📍 NULL은 값을 알수 없는 특수한 상태로 모든 집계 함수는 NULL을 무시하고 통계를 계산한다.

📍 단, 예외적으로 레코드 개수를 세는 COUNT(*)는 NULL 도 포함하지만, 인수로 필드를 지정하면 NULL을 세지않는다.

SELECT AVG(salary) FROM tStaff; 
SELECT SUM(salary)/COUNT(*) FROM tStaff; // 평균은 총합을 개수로 나누어서 구함 위의 문장과 동일

 

 

 

 

📍 score의 경우에는 다른 값이 나온다.

      ➡️ AVG 함수는 NULL 값을 제외하고 계산을 하지만, COUNT(*)의 경우 NULL 값도 포함

      ➡️ 시스템 규칙에 따라 NULL이 0을 나타내는 것일 수 있음.

SELECT AVG(score) FROM tStaff; 
SELECT SUM(score)/COUNT(*) FROM tStaff; 
SELECT SUM(score)/COUNT(score) FROM tStaff;

 

 

 

 

📍 COUNT(*)는 없다는 뜻의 0을 리턴, 다른 집계함수는 계산 대상이 없어서 존재하지 않는 0이 아니라 NULL을 반환

SELECT COUNT(*) FROM tStaff WHERE depart = '비서실'; 
SELECT MIN(salary) FROM tStaff WHERE depart = '비서실';

[ 내용 참고 : IT 학원 강의 ]

 

 

 

 

1. ORDER BY

 

🐰 SELECT 명령에 필드 지정이 없을 경우 레코드의 출력 순서는 DBMS의 디폴트 순서를 따름.

🐰 관계형 DB에서 레코드의 물리적 순서는 큰 의미가 없고, 대신 출력할 때 ORDER BY 절로 정렬 순서를 원하는대로 지정.

// 기본형식
ORDER BY 필드 [ASC | DESC]
 

 

🐰 ORDER BY 다음에 정렬 기준 필드를 적고 오름차순일 경우 ASC 키워드를, 내림차순일경우 DESC 키워드를 지정.

🐰 순서를 생략하면 디폴트인 오름차순으로 적용되므로 키워드 ASC는 보통 생략.

SELECT * FROM tCity ORDER BY popu;
SELECT * FROM tCity ORDER BY popu ASC;
 
 
 
 

🔖  인구수를 기준으로 정렬하여 인구가 작은 도시부터 출력.

 

 

 

 

 

 

SELECT * FROM tCity ORDER BY popu DESC;
 
 

 

 

🔖  DESC를 붙이면 내림차순으로 정렬해서 인구가 많은 도시부터 출력.

 

 

 

 

 


 

 

🐰 두 개 이상의 기준 필드를 지정하는 경우  ➡️  첫 번째 기준 필드의 값이 같으면, 두 번째 기준 필드를 비교하여 정렬 순서를 결정.

SELECT region, name, area, popu FROM tCity ORDER BY region, name DESC;
SELECT region, name, area, popu FROM tCity ORDER BY region ASC, name DESC;
 

 

 
 

 

🔖 지역별로 정렬하되 같은 지역에 속한 도시끼리는 이름의 내림 차순으로 정렬.

🔖 ORDER BY 뒤에 기준 필드를 콤마로 구분하여 나열하되 각 기준별로 오름차순과 내림차순을 따로 지정 가능.

🔖 region은 순서를 지정하지 않았으므로 디폴트인 ASC가적용. 1차 정렬 기준인 지역이 같으면 2차 기준인 이름순으로 정렬하되 이때는 DESC 내림차순으로 정렬.

 

 

 

 

 

SELECT region, name, area, popu FROM tCity ORDER BY area ASC, name DESC;
 

 

 

 

 

 

🔖 area가 동일한 값이 없으므로 두 번째 정렬 기준인 name은 효력을 발휘하지 않음.

 

 

 

 

 

 

 

 

 

 

🐰 ORDER BY 기준은 보통 필드명으로 하지만 순서값으로도 지정 가능. 필드 순서 값은 테이블 생성시에 등록한 순서.

🐰 tCity의 경우 name이 1번, area가 2번, popu가 3번

SELECT * FROM tCity ORDER BY area;
SELECT * FROM tCity ORDER BY 2;
 
 
 
 

 

🔖  면적순으로 정렬하려면 area를 기준으로 하는 대신 2번 필드 기준으로 해도 결과는 같음

 

 

 

 

 

 

 

 

 

 

🐰 테이블에 존재하지 않은 계산값도 정렬 기준으로 사용할 수 있음.

SELECT name, popu * 10000 / area  FROM tCity  ORDER BY popu * 10000 / area;
SELECT name, popu * 10000 / area  AS tmp  FROM tCity  ORDER BY tmp;
 

 

 

 

🔖 인구수와 면적으로 계산한 인구밀도의 오름차순으로 도시를 정렬.

🔖 정렬 기준을 꼭 같이 출력할 필요는 없지만 제대로 정렬했는지 확인하기 위해 인구밀도를 같이 출력

 

 

 

 

 

 

 


 

 

🐰  레코드의 조건을 지정하는 WHERE 절과 출력 순서를 지정하는 ORDER BY 절을 동시에 사용 가능.

SELECT * FROM tCity WHERE region = '경기' ORDER BY area;
 

 

 

🔖  경기도에 있는 도시만 골라 면적별로 정렬.

      이때 ORDER BY 절은 WHERE 절보다 뒤쪽에 있어야 함.

 

 

 


 

 

2. DISTINCT

 

🐰 중복된 값을 제거할 때 DISTINCT 키워드를 붙인다.

    ex. 도시 테이블에서 region 필드만 읽어 도시가 속한 지역의 목록을 조사하고 싶은 경우 SELECT region FROM tCity; 로 작성

            ➡️  하지만 이런 경우 같은 도시가 여럿 있는 경우 중복해서 출력

            ➡️  단순히 어떤 지역이 있는지만 조사한다면 굳이 중복된 값을 반복해서 출력할 필요가 없음

            ➡️  DISTINCT 키워드를 사용하여 중복된 값 제거.

SELECT DISTINCT region FROM tCity;
SELECT DISTINCT region FROM tCity ORDER BY region;
 

 

 

 

🔖  DISTINCT 키워드로 중복 제거를 하다 보면 순서가 달라짐.

🔖  만약 중복도 제거하고 정렬도 하고 싶으면 ORDER BY절을 붙임.

 
 
 
 
 
 

 
 

🐰 DISTINCT의 반대 키워드는 ALL 이며 중복 제거 없이 모든 레코드를 출력.

🐰 ALL이 디폴트라서 굳이 지정할 필요는 없음.

SELECT ALL depart FROM tStaff;
 

 

 

 


 

 

3. LIMIT

 

// 기본 형식
SELECT .... LIMIT [건너뛸 개수], 총개수
 

🐰 LIMIT 구문으로 행수를 제한.

🐰 건너뛸 개수를 생략하면 0으로 적용하여 첫 행 부터 출력

 

SELECT * FROM tCity ORDER BY area DESC LIMIT 4;
SELECT * FROM tCity ORDER BY area DESC LIMIT 0, 4;
 

 

 

🔖  면적이 넓은 상위 4개 도시를 구하는 구문.

 

 

 

 

 

SELECT * FROM tCity ORDER BY area DESC LIMIT 2, 3;
SELECT * FROM tCity ORDER BY area DESC LIMIT 3 OFFSET 2;
 

 

 🔖  앞쪽 2개는 건너뛰고 이후 3개의 행을 구함.

 🔖  앞쪽 몇 개를 건너뛴 후 일정 개수 만큼 보여주는 이 구문은 게시물을 페이지 단위로 끊어서 출력할 때 실용적.

 

 

 

 


 

 

4. OFFSET FETCH

 

🐰  테이블의 일부 레코드만 조회하는 작업은 빈도가 높고 실용적이지만 DBMS 별로 사용하는 문법이 다름.

       ➡️ SQL 표준이 새로 OFFSET FETCH 문법을 만듦.

       ➡️ 일부분을 특정하려면 순서를 지정해야 되서 ORDER BY 문이 반드시 있어야 함.

       ➡️ 그래서 OFFSET FETCH 는 별도의 구문이 아니라 ORDER BY의 옵션

// 기본 형식
ORDER BY 기준필드 OFFSET 건너뛸 행 수 ROWS FETCH NEXT 출력할 행 수 ROWS ONLY;
 
SELECT * FROM tCity ORDER BY area DESC OFFSET 0 ROWS FETCH NEXT 4 ROWS ONLY;
SELECT * FROM tCity ORDER BY area DESC LIMIT 0, 4;
 
 

 

🔖  면적 순으로 상위 4개의 도시를 출력. 면적을 내림차순을 정렬 후 4개의 행만 읽음.

       ➡️ OFFSET을 지정하면 앞쪽 일부를 건너뛸 수 있음.

 

 

 

 

 

SELECT * FROM tCity ORDER BY areabDESC OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY;
SELECT * FROM tCity ORDER BY area DESC LIMIT 2, 3;
 
 
 
 

🔖  상위 2개를 건너 뛰고 다음 순서인 3, 4, 5위 3개의 도시를 조사.

 

 
 
 
 

 

 

🐰 WHERE 구문과 함께 사용하여 필터링을 먼저 하고 그 일부 레코드만 출력할 수 있음.

SELECT * FROM tCity WHERE metro = 'n' ORDER BY area DESC OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY;
SELECT * FROM tCity WHERE metro = 'n' ORDER BY area DESC LIMIT 2, 3;
 
 
 
 

🔖  광역시는 제외하고 순위를 매겨 3등에서 5등까지 출력.

 

 

 

 

 

 

 

 

[ 내용 출처 : IT 학원 강의 ]

 

 


 

1. 필드 비교 [ Where 절 ]

👾 WHERE 절은 읽을 레코드의 조건을 지정. ( * 필드 목록은 읽을 열을 지정하는데 비해 WHERE 절은 읽을 행을 지정 )

      ➡️  주로 필드와 특정값을 비교하는 조건문 형태로 작성한다.

👾 SELECT 명령은 조건에 맞는 레코드를 검색하는 것이 주 기능이어서 대개의 경우 WHERE 절과 함께 사용.

👾 WHERE 절은 DELETE, UPDATE 등의 명령과 함께 삭제 및 변경할 레코드를 선택할 때도 사용.

 

SELECT * FROM tCity WHERE area > 1000;
SELECT name, area  FROM tCity  WHERE  area > 1000;

 

 

📌 면적이 1000제곱킬로미터 보다 큰 도시만 검색.

📌 필드 목록에 * 대신 원하는 필드만 적으면 조건에 맞는 레코드의 지정한 필드만 표시.

📌 조건문은 필드와 상수, 변수 등을 표현식이되고 비교 대상끼리 타입이 호환되어야 함.

      ➡️  정수형을 문자열과 비교한다거나 실수형을 날짜와 비교해서는 안됨.


 

💡 조건문에 사용하는 비교 연산자

연산자
설명
A = B
같다.
WHERE name = '서울'
A > B
A가 더 크다.
WHERE area > 50
A < B
A가 더 작다.
WHERE popu < 100
A >= B
A가 B보다 크거나 같다.
WHERE popu >= 100
A <= B
A가 B보다 작거나 같다.
WHERE area <= 50
A <> B, A != B
A와 B는 다르다. 또는 같지 않다.
WHERE region <> '경기'

 


 

 

👾 숫자는 상수를 그냥 쓰지만 문자열과 날짜 상수는 항상 작은 따옴표로 감싸야 함.

👾 따옴표없이 서울이라고 하면 필드명을 의미.

 

SELECT * FROM `tCity` WHERE `name` = '서울' ( o )
SELECT * FROM tCity WHERE name = '서울' ( o )
SELECT * FROM tCity WHERE name = 서울 ( x )
SELECT * FROM tCity WHERE name = "서울" ( x )

 

 

 

👾 필드의 영문자를 비교할 때는 대소문자 주의. SQL문 자체는 대소문자를 가리지 않아 키워드나 테이블명, 필드명을 아무렇게나 적어도 상관이 없지만, 필드안에 저장된 값은 대소문자를 구분. 필드값의 대소문자 구분 여부는 DBMS에 따라, 설정에따라 다름. 어떤 DBMS를 사용하건 따옴표 내의 문자열 상수는 가급적 대소문자를 정확히적는 것이 바람직.

SELECT * FROM tCity WHERE metro = 'y' ;
SELECT * FROM tCity WHERE metro = 'Y' ;

 

실행 결과

 


 

 

2. NULL 비교

 

👾 NULL은 값이 입력되어 있지 않은 특수한 상태를 표현. 값을 알 수 없거나 아직 결정할 수 없다는 뜻이며 0이나 빈 문자열과는 다름.

👾 필드를 선언할 때 NULL 가능성을 미리 지정한다. 선언문 뒤에 NULL이 있으면 이 필드는 값을 입력하지 않아도 된다는 뜻

 

CREATE TABLE tCity (
name CHAR(10) PRIMARY KEY,
area INT NULL,
popu INT NULL,
metro CHAR(1) NOT NULL,
region CHAR(6) NOT NULL
);

 

 

  📌 인구와 면적이 NULL 가능하다고 되어 있음. 정보가 아직 조사되지 않았거나 모르는 상태일 때 이 필드를 NULL로 남겨 둠.

  📌 반면 광역시 여부나 지역은 NOT NULL로 선언 되어 있어 값이 없으면 레코드를 삽입할 수 없음.

 

 

SELECT * FROM tStaff WHERE score = NULL;       ( x )
SELECT * FROM tStaff WHERE score IS NULL;      ( o )
SELECT * FROM tStaff WHERE score IS NOT NULL;  ( o )

 

  📌 NULL 값을 검색할려고 조건절에서 = NULL 로 작성.

  📌 NULL은 값이 아니라 상태이기 때문에 = 연산자로 비교할 수 없음.

       ➡️ IS NULL 연산자를 따로 제공.

       ➡️ NULL이 아니라는 조건은 IS NOT NULL로 표기.

 

 

 


 

 

3. 논리 연산자

 

👾 두 개 이상의 조건을 동시에 검색할 때는 AND, OR 논리 연산자를 사용

👾 AND는 두 조건이 모두 참인 레코드를 검색하며 OR는 두 조건 중 하나라도 참인 레코드를 검사.

 

SELECT * FROM tCity WHERE popu >=100 AND area >= 700;

 

 

 

📌 인구 100만명 이상, 면적 700제곱킬로미터 이상인 도시를 검색하여

두 조건을 만족하는 부산만 출력.

 

 

SELECT * FROM tCity WHERE popu >=100 OR area >= 700;

 

 

 

 

📌 AND를 OR로 변경하면 두 조건중 하나라도 참인 레코드 검색.

 

 

 

 

 

 

 

👾 세 개 이상의 조건문을 지정할 때도 마찬가지로 WHERE 절을 작성하되 조건의 우선순위에 주의

👾 AND의 우선 순위가 OR 보다 높다. 애매할 경우에는 괄호로 우선 순위를 지정하는 것이 좋음.

 

SELECT * FROM tCity WHERE region = '경기' AND popu >= 50 OR area >= 500;
SELECT * FROM tCity WHERE area >= 500 OR region = '경기' AND popu >= 50 ;

 

 

 

 

📌 경기권 도시중 인구 50만이상이거나 또는 경기권이 아니고 인구가 50만보다 적더라도 면적이 500 이상인 도시를 검색

 

 

 

SELECT * FROM tCity WHERE region = '경기' AND (popu >= 50 OR area >= 500);

 

 

📌 인구가 50만이 넘거나 면적이 500이상인 경기도 도시를 검색.

 

 


👾 NOT 연산자는 표현식의 진위 여부를 반대로 바꿈. 즉 뒤의 표현식이 참이면 거짓으로 바꾸고 거짓이면 참으로 바꾸어 반대 조건을 취함.

SELECT * FROM tCity WHERE region != '경기';
SELECT * FROM tCity WHERE NOT (region = '경기');

 

 

 

 

📌 경기도 소속이 아닌 도시의 정보를 조사. 복합 조건의 반대를 취할때는 NOT이 편리.

 

 

 

 

 

SELECT * FROM tCity WHERE region = '전라' OR metro = 'y'; // 전라도에 있거나 광역시인 도시
SELECT * FROM tCity WHERE region != '전라' AND metro != 'y'; // 위의 조건의 반대
SELECT * FROM tCity WHERE NOT(region = '전라' OR metro ='y');

 

 

📌 A AND B의 부정은 !A OR !B 이며 이를 모르간의 법칙

 


 

 

4. LIKE

 

👾 '=' 비교 연산자를 완전히 일치하는 조건식을 표현하는데 비해 LIKE 연산자는 패턴으로 '부분 문자열'을 검색.

ex. 성이 김씨인 사람, 주소가 강남구인 사람들을 검색할 때 편리

 

⚡️ LIKE 문의 패턴에 사용하는 와일드 카드 ⚡️

 
문자
설명
%
복수 개의 문자와 대응. %자리에는 임의 개수의 임의 문자가 올 수 있음
_
하나의 문자와 대응 _자리에는 하나의 임의 문자가 올수 있음
[]
[]안에 포함된 문자 리스트 중 하나의 문자와 대응
[^]
[^]안에 포함된 문자 리스트에 포함되지 않은 하나의 문자와 대응

👾 임의 개수의 임의 문자와 대응하는 % 와일드 카드를 주로 사용한다.

 

SELECT * FROM tCity WHERE name LIKE '%천%';

 

 

 

📌  이름에 "천"자가 들어가는 도시를 검색

 

 

 

SELECT * FROM tCity WHERE name LIKE '천%';

 

 

📌  "천"으로 시작하는 도시를 검색

 

 

 

SELECT * FROM tCity WHERE name LIKE '%천';

 

 
📌  "천"으로 끝나는 도시를 검색.

📌  '%천'의 경우 처리하는 DBMS나 타입별로 차이가 있음.

📌  공백 제거를 위해 아래와 같이 작성하기도 함.

      SELECT * FROM tCity WHERE TRIM(name) LIKE '%천' ;

 

 


 

 

5. BETWEEN

 

👾 BETWEEN A AND B 문은 "BETWEEN 최소값 AND 최대값" 형식으로 두 값 사이의 범위를 제한

👾 BETWEEN ~ AND 문은 작은 값, 큰 값 순이 상식적이어서 실수할 위험이 낮으며 구문 전체가 하나의 조건이어서 가독성이 높음.

👾 이상, 이하의 범위만 가능하며 미만, 초과는 지정할 수 없는 활용성의 한계가 있음.

👾 문자열이나 날짜에도 사용 가능. ( * 문자열은 사전순으로 비교 )

 

SELECT * FROM tCity WHERE popu BETWEEN 50 AND 100;
SELECT * FROM tCity WHERE popu >= 50 AND popu <= 100;

 

 

 

📌 인구가 50 ~ 100만 사이의 도시를 구함.

📌 "~ 보다 크고 ~ 보다 작다" 조건의 조합이어서 AND 논리 연산자로 대체 가능

 

 

 

SELECT * FROM tStaff WHERE name BETWEEN '가' AND '사';

 

 
SELECT * FROM tStaff WHERE joindate BETWEEN '20150101' AND '20180101';

 

 

 


 

 

 

6. IN

 

👾 BETWEEN 연산자는 연속된 범위만 검색할 수 있으며 불연속적이고 임의적인 값 여러 개를 조사하기 어려움.

👾 이에 비해 IN 연산자는 불연속적인 값 여러 개의 목록을 제공하여 이 목록과 일치하는 레코드를 검색.

👾 IN 연산자 뒤의 괄호 안에 콤마로 구분된 값 목록을 나열하여 이 중 하나에 해당하는지 점검.

👾 값 개수에는 제한이 없다.

 

SELECT * FROM tCity WHERE region IN ('경상','전라');
SELECT * FROM tCity WHERE region = '경상' OR region = '전라';

 

 

📌  region 필드가 '경상' 또는 '전라'인 모든 도시를 조사.

📌  IN 연산자는 여러 값 중 하나라도 해당하는지 점검하므로 각각의 비교문을 OR 논리 연산자로 연결하여 표현가능.

 

 

 

 

👾  값 리스트가 많은 경우 일일히 OR 연산자로 조건을 연결하는 것보다 IN 연산자로 값만 나열하는 것이 짧고 읽기 쉬움.

      추후 값 리스트를 편집하기도 편해 관리상의 이점이 있음.

👾  IN 연산자의 반대 조건은 NOT IN

 

SELECT * FROM tCity WHERE region NOT IN ('경상','전라');

 

 

 

📌  경상도와 전라도에 있지 않은 도시 목록을 조사

 

 

 

 

 

 

👾  부분 문자열 여러 개 중 하나에 해당하는지 찾으려면 LIKE와 IN 연산자를 같이 써야 하지만 SQL 표준에서 지원하지 않음.

      ➡️  즉 LIKE와 IN 연산자는 같이 사용할 수 없음. 이런 검색을 하고 싶으면 각각의 LIKE 조건을 OR 연산자로 연결

 

SELECT * FROM tStaff WHERE name LIKE IN ('이%', '안%'); ( x )
SELECT * FROM tStaff WHERE name LIKE '이%' OR name LIKE '안%';

 

 

 

 

📌  직원 목록에서 이씨와 안씨를 찾음

 

 

 

 

 

 

 

 

[ 내용 출처 ; IT 학원 강의 ]


 

1. 기본 형식

💡 SELECT테이블의 데이터를 읽어 출력하는 동작으로 조회라고 함.

    ➡️  테이블을 조회하는 것은 가장 기본적인 동작이며 SELECT 문은 모든 SQL 명령중 사용 빈도가 압도적으로 높음.

    ➡️  테이블을 읽은 동작은 단순하지만 옵션이 굉장히 많음.

       ex. 관심있는 필드만 읽거나 조건을 지정하여 일부 레코드만 조회하거나 정렬 기준을 지정하여 출력 순서를 조정할 수 있음.

// 기본 형식
SELECT 필드목록 FROM 테이블 [WHERE 조건 ] [ORDER BY 정렬기준]
SELECT * FROM tCity;

 

 

 🔎  FROM 절의 테이블에서 필드를 읽어 출력하는 명령.

 🔎  SELECT와 FROM 사이에 필드목록에 출력할 필드의 이름을 지정하되 

       * 기호를 쓰면 테이블의 모든 필드를 출력.

 

 

 


 

2. 필드목록

💡 필드목록의 *는 모든 필드를 의미하며 All 또는 몽땅이라고 읽음.

      ➡️ 표기법이 짧아 입력하기 편하고 필드 이름을 몰라도 되므로 테이블을 살펴볼 때 간편하다.

💡 일부 필드만 출력하거나 순서를 직접 지정할 때는 SELECT 와 FROM 사이에 원하는 필드만 콤마로 구분하여 적는다.

      ➡️ 목록에 있는 필드만 읽으니 빠르고 출력 결과도 짧음.

SELECT name, area, popu FROM tCity;
SELECT region, name, popu FROM tCity;

   

    ✔️ 도시명과 인구수에만 관심이 있다면 name 필드와 popu 필드만 목록에 적음.

    ✔️ 두번째 쿼리문은 지역과 도시명, 인구수를 출력하는데 필드 순서를 마음대로 지정 가능.

           ➡️  테이블에는 region 필드가 name 필드보다 뒤에 있지만 필드 목록에 지정한 순서대로 출력.

 

  🌟 두 명령의 차이점

SELECT name, area, popu, metro, region FROM tCity;
SELECT * FROM tCity;

   

    ✔️ tCity의 모든 필드를 일일이 적거나 * 로 모든 필드를 지정하지만 결과는 같음.

          ➡️  하지만 테이블의 디자인이 바뀌게 되면 결과 값이 달라짐.

    ✔️ 단순 확인을 할 때는 *를 사용해도 되지만 실무에서는 가급적 필드의 이름과 순서를 명확히 지정하는 것이 유리.


3. 별명

 

💡 SELECT 명령이 출력하는 내용을 결과셋 Result Set 또는 로우셋 Row Set 이라고 하는데 형태가 테이블과 동일.

     - 결과셋의 필드 캡션은 테이블에서 정의한 이름과 동일.

        ex. name 필드는 name이라고 출력하고, popu는 popu라고출력.

💡 테이블의 필드명은 구분 가능하고 입력하기 쉬운 짧은 명칭일 뿐, 사용자가 읽기에는 직관적이지 못한 경우가 많음.

      ➡️  이 경우 필드에 대한 별명 Alias를 지정하며 결과셋의 헤더에 필드 이름 대신 별명을 출력.

      ➡️  별명은 어디까지나 문자열일 뿐이므로 명칭 규칙에 영향을 받지 않고 모든 문자를 자유롭게 표기할수 있음.

필드명 [AS] "별명"

 

💡 필드명과 별명 사이에 전치사 AS를 넣어서 표현.

      ➡️  이 때 별명은 공백이나 특수 문자를 포함할 수 있어서 큰 따옴표로 감싸되 평이한 단어이면 따옴표 생략 가능.

SELECT name AS 도시명, area AS "면적(제곱Km)", popu AS "인구(만명)" FROM tCity;

실행 결과

 

💡 별명을 사용하는 다른 이유로는 언어에 따라 명칭을 구성하는 규칙이 달라 특수한 이름을 읽지 못하는 경우가 있고, DBMS별로 키워드가 달라 필드명으로 쓰지 못하는 단어 있음. 이런 경우 결과셋에 별명을 붙이면 개발툴이나 DBMD에 상관없이 일관된 별명으로 필드를 읽을 수 있음.

💡 DBMS에 따라 큰 따옴표만 사용가능하거나, 작은 따옴표도 사용 가능한 경우가 있음.

💡 SQL Server는 다음 구문도 가능

 

SELECT 도시명 = name, area '면적(제곱Km)', popu [인구(만명)] FROM tCity;

 


 

4. 계산값의 출력

💡 필드목록에 필드 이름을 적으면 필드 값이 그대로 출력.

     ex. SELECT popu라고 하면 테이블의 인구수를 출력.

            ➡️  하지만 popu 필드의 단위가 만명으로 되어 있어서 헷갈릴 수 있다!

💡 필드 목록에 계산식을 사용하면 테이블에 저장된 값을 가공하여 출력 된다.

 

SELECT name, popu * 10000 AS "인구(명)" FROM tCity;

실행 결과

 

    🔎 테이블에는 요약적으로 압축하여 저장하기 때문에 실제 정보와 다른 경우가 있음.

         이럴때는 계산식으로 사용자가 읽기 쉬운 형태로 가공해서 보여주는게 바람직.

    🔎 계산식을 사용하면 테이블에 없는 정보도 만들어서 표시할 수 있다.

 

SELECT name, area, popu, popu * 10000 / area FROM tCity;
SELECT name, area, popu, popu * 10000 / area AS "인구밀도" FROM tCity;

실행 결과

 

    ✔️ tCity 테이블에는 도시의 면적과 인구수 정보가 있는데 이 둘을 계산하면 제곱킬로미터당 인구수인 인구밀도를 구할 수 있음.

    ✔️ 계산에 의해 구한 필드는 이름이 없으므로 설명적인 별명을 붙이는 것이 좋음.

    ✔️ 꼭 테이블에 있는 필드만 출력할 수 있는게 아니라, 테이블과 상관없는 단순한 계산식도 출력 가능.

 

SELECT 60 * 60 * 24 AS "하루" FROM dual;

 

실행 결과

 

    ✔️ SELECT 수식 FROM dual; 명령은 간단한 계산기 역할.

    ✔️ dual 은 1행 1열짜리 더미 테이블.

 

[ 내용 출처 ; IT 학원 강의 ]


1. 데이터베이스의 정의와 특징

✔️ 데이터베이스를 ‘데이터의 집합’이라고 정의한다면 DBMS는 이 데이터베이스를 관리·운영하는 역할을 한다.

✔️ 데이터베이스는 여러 명의 사용자나 응용 프로그램을 공유하고 동시에 접근이 가능해야 한다. 그래서 Microsoft의 Excel과 같은 프로그램은 데이터의 집합으로 사용될 수 있기 때문에 DBMS와 비슷하게 보일 수도 있지만, 대용량을 관리하거나 여러 명의 사용자가 공유하는 개념은 아니므로 DBMS라 부르지 않는다.

✔️ 데이터베이스는 ‘데이터의 저장공간’ 자체를 의미하기도 한다. 특히, MySQL에서는 ‘데이터베이스’를 자료가 저장되는 디스크 공간(주로 파일로 구성됨)으로 취급한다.

 


2. DBMS 란?

✔️ 파일시스템의 단점을 보완하고 대량의 데이터를 보다 효율적으로 관리하고 운영하기 위해서 사용되기 시작한 것이 DBMS (DataBase Management System)

✔️ DBMS는 데이터의 집합인 ‘데이터베이스’를 잘 관리하고 운영하기 위한 시스템 또는 소프트웨어를 말한다.

✔️ DBMS에 데이터를 구축하고 관리하고 활용하기 위해서 사용되는 언어가 SQL Structured Query Language 이다.

-> 이 SQL을 사용해서 우리가 DBMS를 통해 중요한 정보들을 입력하고 관리하고 추출할 수 있다.

(1) 관계형 데이터베이스 Relational DBMS: RDBMS

· 시초는 1969년 E.F.Codd라는 학자가 수학 모델에 근거해서 고안하면서 시작되었다.

  RDBMS의 핵심 개념은 “데이터베이스는 테이블 Table 이라 불리는 최소 단위로 구성되어 있다."

· 테이블은 데이터를 효율적으로 저장하기 위한 구조이다. 정보를 저장하기 위해서 하나의 테이블이 아닌 여러 개의 테이블로 나누어서 저장함으로써 불필요한 공간의 낭비를 줄이고 데이터 저장의 효율성을 보장해 줄 수 있다.

 

아이디
이름
주소
abc123
한가인
서울 은평구 00동
def456
김태희
인천 남구 00동
ghi789
송혜교
경기도 부천시 00동

 

[ 4행(로우) 3열(컬럼) 관계형 구조 ]

 


3. SQL 이란?

✔️ 관계형 데이터베이스에서 사용되는 언어

✔️ DBMS 제작회사와 독립적이며 다른 시스템으로 이식성이 좋다. 대화식 언어로 구성되어 있고 분산형 클라이언트/서버 구조.

(1) MySQL

· Oracle 사에서 제작한 DBMS 소프트웨어로 오픈 소스로 제공된다. 오픈소스란 말그대로 소스를 공개한 소프트웨어를 말한다.

· 상용 목적의 Standard/Enterprise/Cluster CGE, 무료 에디션인 Community 를 제공한다.

 

( 내용 출처 : 이것이 MySQL이다. )

+ Recent posts