TigerCow.Door



안녕하세요 문범우입니다.

이번 포스팅에서는 IN, EXISTS, NOT IN, NOT EXISTS 에 대해서 보다 상세하게 알아보려고 합니다.

해당 내용은 꼭 SQL Server 뿐만 아니라 MySQL 등에서도 포괄적으로 적용되는 내용입니다.



0. 데이터 세팅


먼저 각 구문에 대해서 비교를 할 때 보다 쉽게 확인할 수 있도록 가상 데이터를 세팅해보도록 하겠습니다. 총 2개의 테이블을 생성하며 각 테이블의 이름과 데이터는 아래와 같습니다.


SELECT * FROM TB_FOOD;




SELECT * FROM TB_COLOR;




1. IN


SELECT * FROM TB_FOOD f

WHERE f.number IN (SELECT c.number FROM TB_COLOR c);


위와 같은 쿼리를 실행하면 어떤 결과가 나올까요?

먼저 결과를 살펴보면 다음과 같습니다.



이는 우리가 어느정도 예상할 수 있는 결과입니다. 하지만 실제로 IN 을 포함한 쿼리가 어떻게, 어떤 식으로 작동되는지 알아야 이후에 EXISTS 또는 NOT IN / NOT EXISTS와 헷갈리지 않습니다.


위의 쿼리에서는 제일먼저 TB_COLOR 테이블에 접근하게 됩니다.

즉, IN 뒤에 있는 괄호의 서브쿼리를 먼저 실행해서 그에 대한 요소를 가져오는 것이죠.

따라서 사실 IN뒤에 괄호안에는 서브쿼리 이외에도 직접 요소값을 적어줄 수 있습니다.


이후에는 TB_FOOD에서 하나의 레코드를 가져오며 그 레코드의 number 값이 앞에서 가져온 IN 이하의 요소들에 포함되어 있는지를 체크합니다. 그리고 IN 이하의 요소들 중 하나라도 일치한다면 그 레코드를 출력하게 되는 것이죠.


여기서 중요한 것은, 쿼리에서 TB_COLOR에 먼저 접근하여, number 값들을 가져와 리스트로 IN 이하에 뿌려주고, 그 이후에 TB_FOOD에서 하나의 레코드씩 IN 이하의 요소들과 일치하는지 비교한다는 것 입니다.



2. EXISTS


그럼 EXISTS는 어떻게 동작하는지 쿼리와 그 결과를 보도록 합시다.


SELECT * FROM TB_FOOD f

WHERE EXISTS (SELECT c.number FROM TB_COLOR c);



무언가 이상합니다. 우리가 기대했던 결과와는 달리 TB_FOOD 테이블이 그대로 출력되었습니다. 왜 이럴까요? 이는 EXISTS 구문에 대해서 정확히 알지 못하고 잘못 사용하였기 때문에 나온 결과입니다.


위의 쿼리를 기준으로 DB가 어떻게 동작하는지 한번 알아보겠습니다.

IN구문에서는 IN 이후에 나오는 소괄호 내부의 서브쿼리에 대해서 먼저 접근하였습니다. 하지만 EXISTS 구문에서는 다릅니다. 먼저 TB_FOOD에 접근하여 하나의 레코드를 가져오고 그 레코드에 대해서 EXISTS 이하의 서브쿼리를 실행하고 서브쿼리에 대한 결과가 '존재하는지'를 확인합니다.


예시를 들어 생각해보면, 제일 처음에 [ 1 / 치킨 ] 이라는 레코드를 가져왔을 것이고, 해당 레코드에 대해서 SELECT c.number FROM TB_COLOR c 쿼리를 통해 결과가 나오는지 확인합니다. 이때 서브쿼리에 대해 어떠한 결과라도 존재하기만 한다면 참이 되어서 [ 1 / 치킨 ] 레코드가 출력됩니다.

그런데 SELECT c.number FROM TB_COLOR c 쿼리는 사실 TB_FOOD의 어떠한 레코드하고도 연관이 없이 항상 결과값을 가지는 쿼리입니다. 따라서 TB_FOOD의 모든 레코드가 출력되는 것 이죠.


그럼 이를 우리가 기대하는 결과대로 출력하도록 하기 위해서는 다음과 같이 쿼리를 수정하면 됩니다.


SELECT * FROM TB_FOOD f

WHERE EXISTS (SELECT c.number FROM TB_COLOR c WHERE c.number = f.number);



이렇게 나온 결과는 사실 IN 구문과 같은 결과를 출력합니다. 하지만 내부적으로 쿼리가 동작하는 방식은 아예 다르다는 것에 주의하시길 바랍니다. 그러한 내부 로직에 따라서 성능차이도 크게 발생하기 때문입니다.



3. NOT IN


이번에는 NOT IN 구문입니다.

먼저 쿼리와 그 결과를 보고 함께 생각해보겠습니다.


SELECT * FROM TB_FOOD f

WHERE f.number NOT IN (SELECT c.number FROM TB_COLOR c);



위의 쿼리를 실행하니 위의 사진과 같이 아무런 결과도 출력되지 않았습니다. 왜 그럴까요?

우리가 처음에 알아본 IN의 방식에 대해서 알아봅시다. IN은 먼저 소괄호의 서브쿼리를 실행합니다. 그럼 SELECT c.number FROM TB_COLOR c 의 쿼리가 실행되고 그 결과로 다음의 리스트가 반환됩니다.


( 1, 2, 3, 4, 5, 6, NULL )


즉, 초기의 쿼리는 다음과 같은 쿼리인 것입니다.


SELECT * FROM TB_FOOD f

WHERE f.number NOT IN ( 1, 2, 3, 4, 5, 6, NULL );


그럼 이제 TB_FOOD에서 하나의 레코드씩 가져올 것이고 IN이 아니라 NOT IN 구문이기 때문에 소괄호의 요소들과 일치하지 않아야 결과로 반환됩니다.


TB_FOOD의 레코드들 중에서 [ 7 / 사탕 ] 레코드를 예로 들어서 생각해보면 해당 레코드의 number 값인 7이 NOT IN 이하의 소괄호에 있는지 확인하면 됩니다. 분명히 7이라는 요소는 존재하지 않습니다. 따라서 우리의 생각대로 라면 해당 레코드는 결과로 출력되어야 하는데 위에서 본 것 처럼 출력되지 않았습니다. 왜 일까요?


이는 DB 에서 해당 요소가 NOT IN 이하의 소괄호의 요소들에 대한 포함여부를 어떻게 판단하는지를 알면 쉽게 이해할수 있습니다. 사실 위의 쿼리는 아래의 쿼리와 같이 동작함으로써 NOT IN 이하의 소괄호에 대한 포함 여부를 판단하게 됩니다.


SELECT * FROM TB_FOOD f

WHERE f.number != 1

AND f.number != 2

AND f.number != 3

AND f.number != 4

AND f.number != 5

AND f.number != 6

AND f.number != NULL;

즉, NOT IN 구문은 TB_FOOD에서 가져온 레코드의 number 값이 소괄호의 모든 요소들과 일치하지 않는지를 체크하는 것입니다. 그런데 위에서는 number 값이 NULL과 연산을 진행하게 되는데, 이때 NULL과의 비교연산은 항상 UNKNOWN 값을 반환하게 됩니다. 따라서 WHERE 절 이하가 TRUE가 아니므로 해당 레코드가 출력되지 않게 되는 것이죠.


이렇게 NOT IN이 어떻게 동작하는지를 알고보니 결국 TB_COLOR에 존재하는 NULL 때문에 우리가 기대하던 결과가 나오지 않음을 알 수 있었습니다. 그럼 우리가 기대한 결과가 나오게 하려면 다음과 같이 쿼리를 수정하면 됩니다.


SELECT * FROM TB_FOOD f

WHERE f.number NOT IN (SELECT c.number FROM TB_COLOR c WHERE c.number IS NOT NULL);


 



4. NOT EXISTS


그럼 마지막으로 NOT EXISTS에 대해서 알아보도록 하겠습니다.

오히려 NOT EXISTS는 위에서 EXISTS에 대해서 이해했다면 크게 어려운 점이 없습니다. 하지만 그 결과가 NOT IN과 약간 다르죠. 쿼리와 결과를 먼저 보도록 하겠습니다.


SELECT * FROM TB_FOOD f

WHERE NOT EXISTS (SELECT c.number FROM TB_COLOR c WHERE c.number = f.number);



위에서 NOT IN을 사용했을 때에는 number 값이 NULL인 레코드는 출력되지 않았습니다. 그 이유를 다시 생각해보자면, IN 구문은 요소간에 비교 연산으로 레코드가 출력되는데 NULL 값에 대한 비교연산은 항상 UNKNOWN을 반환하기 때문이었습니다. 

하지만 앞에서 알아볼 때 EXISTS 구문은 다르게 동작했습니다. 위 쿼리를 기준으로 한다면 먼저 TB_FOOD에서 레코드를 가져오고 해당 레코드의 number를 NOT EXISTS 이하의 서브쿼리에 전달하여 해당 서브쿼리에서 값이 존재하는지를 확인합니다. EXISTS 구문이었다면 값이 존재할 때 해당 레코드를 출력하지만, NOT EXISTS 구문이기에 해당 서브쿼리의 값이 존재하지 않으면 해당 레코드를 출력합니다.


여기서 NULL이 출력하는 과정을 한번 더 자세하게 알아보자면, [ NULL / 타코 ] 레코드를 예로 들었을 떄, number = NULL 입니다. 따라서 NOT EXISTS 이하의 쿼리를 확인해보면 다음과 같을 것 입니다.


SELECT c.number FROM TB_COLOR c WHERE c.number = NULL;


이때 우리가 NOT IN에서 알아본 것과 같이 NULL에 대한 비교연산은 항상 UNKNOWN 값을 반환하므로 해당 쿼리의 결과가 존재하지 않게 되고, 이에 따라서 [ NULL / 타코 ] 레코드가 출력되는 것 입니다.



이렇게 IN, EXISTS, NOT IN, NOT EXISTS 에 대해서 알아보았습니다.

저 또한 많이 헷갈리던 개념들아었는데 다시 한번 정리하고 나니 확실히 개념이 잡히는 것 같습니다. IN과 EXISTS는 성능에 대해서도 많은 이슈를 가져오는 구문들이니 그 차이를 확실히 짚고 넘어가는 것을 추천드립니다.


혹시 내용이 잘못되었거나 더 궁금하신 점이 있다면 언제든지 말씀해주시면 감사하겠습니다.

블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 rollup, cube, case, pivot에 대해서 함께 알아보도록 하겠습니다.



먼저 이전의 글에서 만들었던 sample데이터를 통해 실습을 진행해보도록 하겠습니다.


SELECT * FROM employee;




1. ROLLUP


먼저 알아볼 함수는 ROLLUP 입니다.

ROLLUP은 GROUP BY문과 함께 사용되는 함수인데, GROUP BY로 GROUPING된 행들 데이터 총합을 나타는데 사용합니다.

즉, employee테이블에서 부서별 그리고 직급 별 급여 합과 총합을 구하기 위해서 ROLLUP이 사용될 수 있습니다.


SELECT deptNo, job, SUM(salary) 급여총합

FROM employee

GROUP BY deptNo, job with ROLLUP;



사실상 부서별 그리고 직급별 급여의 합을 구하는 것은 SUM함수를 통해서 할 수 있었습니다.

하지만 위의 결과에서 빨간색으로 음영처리해놓은 결과는 이전의 SUM함수를 통해서 얻을 수 없었습니다.

첫번째 빨간색 음영 박스가 의미하는 것은 deptNO이 10인 부서에서 모든 직급(모든 job)의 급여총합을 의미합니다.

즉, deptNO이 10인 행들끼리 job을 모두 감았다(roll up)는 의미로 생각하시면 될 것 같습니다.

그리고 우리가 GROUP BY를 deptNo, job 로 GROUPING하였기 때문에, job으로 ROLLUP된 행 3개와 deptNO으로 ROLLUP 된 마지막 행(15번째 행)까지 총 4개의 추가 행이 결과로 나오게 됩니다.



2. CUBE


이번에는 CUBE에 대해서 알아봅니다.

쉽게 생각하면 CUBE는 ROLLUP 함수의 확장 형태라고 볼 수 있습니다.

우리가 위의 예에서 deptNo, job으로 ROLLUP을 진행하니, deptNo 끼리 job으로 묶인 salary의 총합(3개 행)과 deptNo와 job으로 묶인 salary의 총합(1개행)의 추가 데이터를 얻을 수 있었습니다.

만약 ROLLUP을 job, deptNo으로 진행했다면 어떨까요?

job끼리 deptNo으로 묶인 salary의 총합(6개 행 = job의 종류가 6개)과 job과 deptNo로 묶인 salary의 총합(1개행)의 추가 데이터를 얻을 수 있습니다.

CUBE는 이렇게 GROUPING 할 때 언급한 열의 순서에 따라 나타날 수 있는 ROLLUP의 경우의 수를 모두 나타내주게 됩니다. 그럼 바로 확인해보도록 하겠습니다.


SELECT deptNo, job, SUM(salary) 급여총합

FROM employee

GROUP BY deptNo, job with CUBE;



위의 결과를 보시면 먼저 3행은 과장 직급의 급여총합을 구한 것이며, 동일하게 5행, 9행, 13행, 15행, 17행은 각 직급별 급여총합을 나타내고 있습니다.

그리고 18행은 모든 deptNo와 job의 급여 총합을 나타내주고 있으며, 19행, 20행, 21행은 deptNo별 급여총합을 나타내고 있습니다.

위의 쿼리문을 아래와 같이 하면 행의 순서는 바뀔 수 있지만 결과는 동일합니다


SELECT deptNo, job, SUM(salary) 급여총합

FROM employee

GROUP BY job, deptNo with CUBE;



3. CASE


이번에 알아볼 CASE문은 C언어나 Java와 같은 프로그래밍 언어에서 사용되는 if ~ else ~ 문 또는 switch 문과 개념적으로 동일합니다.

기본적인 형식은 아래와 같습니다.


CASE when 조건식1 then 결과 1

          when 조건식1 then 결과2

          ...

          [ELSE 결과]

END [AS 칼럼 명]


여기서 대괄호로 표시된 것들은 생략할 수 있습니다.


CASE문은, 우리가 employee 테이블에서 부서별로 부서명을 직접 나타내고 싶을 때와 같은 경우에 사용할 수 있습니다. 부서번호가 10인 경우 전산부, 20인 경우 인사부, 30인 경우 경리부, 40인 경우 영업부로 나타내고 이 외에는 미정이라고 나타내보도록 합시다.


SELECT empName, deptNo,

CASE WHEN dpetNo = 10 THEN '전산부'

WHEN deptNo = 20 THEN '인사부'

WHEN deptNo = 30 THEN '경리부'

WHEN deptNo = 40 THEN '영업부'

ELSE '미정'

END AS 부서명

FROM employee;



위와 같이 우리가 조건을 설정한 대로 부서명이 올바르게 출력되었습니다.

조건식에는 범위에 대한 조건도 설정할 수 있습니다.


만약 부서번호가 20이하인 경우는 부서위치가 1층, 20초과인 경우에는 부서위치가 2층인 것으로 나타내고자 하면 다음과 같이 할 수 있습니다.


SELECT empName, deptNo,

CASE WHEN deptNo <= 20 THEN '1층'

WHEN deptNo > 20 THEN '2층'

END AS 부서위치

FROM employee;




4. PIVOT / UNPIVOT


마지막으로 알아볼 것은 PIVOT과 UNPIVOT입니다.

먼저 PIVOT에 대해서 알아보도록 하겠습니다.

PIVOT은 행으로 되어 있는 데이터를 열로 변환해서 표현하는 함수입니다.


우리가 가지고 있는 employee 테이블에서 열을 deptNo과 각 직급으로 나타내어 그 값을 표현하려면 어떻게 해야 할까요? 기존의 직급 데이터는 'job'이라는 속성에 행으로써 존재 했습니다. 하지만 사원, 부장 과 같이 행으로 되어있던 데이터를 열로 나타내려면 PIVOT을 사용하면 됩니다.

PIVOT문의 기본 형태는 다음과 같습니다.


SELECT [PIVOT열1], [PIVOT열2], ...

FROM 테이블명

PIVOT(나타내고자하는 값, FOR 행->열로 바꿀 열 IN ([PIVOT열1], [PIVOT열2], ...)) as 별칭


PIVOT문은 조금 어려울 수 있기 때문에 바로 실제 쿼리를 보면서 이해하시는 것을 추천드립니다.

위에서 이야기한 바를 쿼리로 나타내면 다음과 같습니다.


SELECT deptNo, [사원], [대리], [과장], [부장], [차장], [사장]

FROM employee

PIVOT(SUM(salary) FOR job In([사원], [대리], [과장], [부장], [차장], [사장])) AS job

ORDER BY deptNo;



위와 같이 행으로 되어있던 값을 열로 나타내어 테이블의 형태를 재구축 할 수 있습니다.

UNPIVOT과 같은 경우도 PIVOT과 활용법이 동일하지만 PIVOT이 행->열의 방식이었다면 UNPIVOT은 열->행의 방식인 것만 고려하면 됩니다.


블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 SUM, AVG, MIN, MAX와 같은 집계함수들에 대해서 알아보면서 GROUP BY절HAVING절에 대해서 다뤄보도록 하겠습니다.


1. 집계함수


집계함수는 값에 대해서 특정 연산을 수행하는 함수들을 이야기합니다.

합계를 구하는 SUM함수나 평균을 구하는 AVG함수, 개수를 세는 COUNT함수 등이 대표적입니다.

그럼 아래와 같이 이전 포스팅에서 사용했던 SampleDB를 사용하여 몇가지 집계함수에 대해서 함께 알아보도록 하겠습니다.




- SUM


SUM함수는 말 그대로 합계를 구하는 함수 입니다.

employee 테이블에서 연봉의 합계를 구하고자 할 때와 같은 경우에 아래와 같이 사용할 수 있습니다.


SELECT SUM(salary) FROM employee;




그럼 이번에는 employee 테이블에서 commission의 합계를 구해볼까요?

하지만 commission에는 NULL값이 포함되어 있습니다. 이전에는 NULL에 대한 연산을 진행할 때 그 결과가 NULL이 나오게 되어서 ISNULL이라는 함수를 이용했습니다.

그럼 집계함수에서는 어떨지 한번 확인해볼까요?


SELECT SUM(commission) FROM employee;



위의 결과에서 볼 수 있듯이 집계함수에서의 NULL은 무시가 됩니다.



- AVG


이어서 AVG함수에 대해서 알아봅시다.

AVG함수는 평균을 구하는 함수입니다. 그럼 월급의 평균은 어떠한지 확인해보도록 하겠습니다.


SELECT AVG(salary) FROM employee;



AVG함수 또한 NULL값이 존재할 때에는 NULL값은 무시하고 평균을 구하게 됩니다.



- MIN, MAX


MIN과 MAX는 최대값과 최소값을 구하는 함수 입니다.

다음과 같이 월급의 최소값과 최대값을 구해보도록 하겠습니다.


SELECT MIN(salary), MAX(salary) FROM employee;




- COUNT


마지막으로 알아볼 COUNT 함수는 개수를 세는 함수입니다.

이때 COUNT 또한 NULL값은 무시하게 됩니다. 즉, 값이 존재하는 데이터에 대한 개수만 세는 것이죠.

따라서 salary의 COUNT값과 commission의 COUNT값은 서로 다릅니다.


SELECT COUNT(salary), COUNT(commission) FROM employee;





2. GROUP BY


그런데 만약, 직급별 월급 평균, 월급 합계 등 특정 그룹별로 집계함수를 사용하고 싶을때는 어떻게 할까요?

테이블에서 특정 그룹을 만들 수 있도록 하는 것이 바로 GROUP BY 절 입니다.


즉, GROUP BY 'A' 라고 한다면 A칼럼에서 같은 것끼리 묶어서 하나의 GROUP를 만드는 것이죠.


그럼 바로 GROUP BY를 활용해보도록 하겠습니다.

위에서 이야기한 바와 같이 직급별 월급 평균은 다음과 같이 구할 수 있습니다.


SELECT job 직급, AVG(salary) 월급평균

FROM employee GROUP BY job;



위와 같이 직급별로 GROUP이 되어 AVG함수의 값이 나오는 것을 볼 수 있습니다.


하지만 우리가 다음과 같이 SELECT 문을 구성한다면 어떻게 될까요?


SELECT empName 이름, job 직급, AVG(salary) 월급평균

FROM employee GROUP BY job;


위의 구문을 실행시키면 아래와 같이 오류가 발생하게 됩니다.



오류메세지를 읽으며 한번 왜 오류가 발생하는지 생각해봅시다.

우리가 출력하고자 하는 empName 값이 집계함수에도 없고, GROUP BY 절에도 없어서 사용할 수 없다고 하네요.

그럼 empName이 집계함수나 GROUP BY 절에 있어야 한다는 의미인데, 왜 그럴까요?


우리가 결과를 출력하는 입장이라고 한번 생각해봅시다.

empName이 없을 때는 이전의 결과와 같이 직급과 월급평균을 잘 출력할 수 있었습니다.

예를 들어 과장의 월급평균은 483이란 결과를 가져왔죠.

그런데 이때 해당 레코드(행)에 empName을 출력해야 한다면, 어떠한 empName을 출력해야 할까요?

즉, 과장 직급의 483의 평균월급이라는 레코드는 '과장'이라는 값으로 여러개의 레코드가 그룹이 되어 있는 레코드 입니다. 즉 해당 레코드에는 여러개의 empName이 존재하는 것이죠.

따라서 SQL에서는 그 여러개 중에서 하나를 출력할 수 없기에 오류가 발생하는 것입니다.

만약 empName이 집계함수를 적용시키면 집계함수에 따른 값이 나오겠죠, 물론 문자열 값이기에 또 다른 오류가 발생하겠지만..

또한 empName을 GROUP BY절에 다시 써주면 아래와 같이 job과 empName이 동일한 레코드끼리 묶여서 나오기 때문에 사실상 현재 데이터에서는 모든 데이터를 출력하는 것과 같게 됩니다.


SELECT empName 이름, job 직급, AVG(salary) 월급평균

FROM employee GROUP BY job, empName;




3. HAVING


이번 포스팅에서 마지막으로 알아볼 것은 HAVING절 입니다.

HAVING은 간단하게 말해서, 우리가 위에서 배운 GROUP BY절을 통해 만들어진 GROUP에 대해서 조건을 거는 것 입니다.


그런데 우리는 이전에 조건을 거는 WHERE절에 대해서 학습하였습니다.


WHERE절과 HAVING절의 차이는 무엇일까요?


기본적으로 WHERE절은 모든 레코드(행)에 대해서 조건을 적용하게 됩니다.

하지만 HAVING절은 GROUP BY절을 통해 만들어진 GROUP 들에만 조건을 적용하는 것이죠.


이를 잘 이해하지 못하면 추후에 HAVING과 WHERE 사용에 있어 헷갈릴 수 있습니다.


그럼 바로 사용해보도록 하겠습니다.

각 직급에 대해 3명 이상인 직급과 그 인원수를 출력해보도록 하겠습니다.


SELECT job 직급, COUNT(job) '직급 수' FROM employee

GROUP BY job HAVING COUNT(job) >= 3;



위와 같이 사용됩니다.


그럼 만약,

"월급이 300만원 이상인 사람들에 대해서 직급별로 2명이상인 직급과 그 직급의 월급 평균을 구해라."

라면 어떻게 해야 할까요?

위와 같은 경우에 바로 WHERE절과 HAVING절이 같이 사용하게 됩니다.


SELECT job 직급, AVG(salary) 월급평균 FROM employee

WHERE salary >= 300

GROUP BY job HAVING COUNT(job) >= 2;



추후에 더 많은 데이터들을 대상으로 복잡한 쿼리문을 다루게 되면 충분히 헷갈릴 수 있는 점들이니 꼭 스스로 쿼리문을 작성해보면서 이해하기를 바랍니다.



이렇게 해서 집계함수와 GROUP BY, HAVING 절에 대해서 알아보았습니다.

궁금하거나 잘못된 점은 언제든 댓글이나 이메일, 카카오톡을 통해서 문의주시면 감사하겠습니다.


블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

지난 글에서 기초적인 SELECT문을 통해 데이터를 조회하는 방법에 대해서 알아보았습니다.

이번 포스팅에서는 SELECT문에 WHERE절을 추가하여 특정 조건에 부합하는 데이터들만 조회하는 방법에 대해서 알아보도록 하겠습니다.


데이터베이스 및 테이블들은 지난 글에서 만든 샘플데이터를 그대로 이용합니다. 해당 샘플 데이터가 없는 분들은 아래 글에서 쿼리를 통해 샘플데이터를 생성하고 진행해주세요.


[MS SQL Server] #5_SELECT문 기초



1. WHERE문 기초


먼저 아래와 같은 기본 SELECT문을 통해서 employee 테이블의 모든 데이터를 조회해보도록 합시다.


SELECT * FROM employee;


그런데 만약 위와 같이 모든 정보를 얻고 싶은 것이 아니라, job의 값이 '사원'인 데이터에 대해서만 조회하고 싶을 때는 어떻게 할까요?

또는 salary가 500 이상인 데이터만 조회하고 싶을 때는 어떻게 해야 할까요?


이와 같이 테이블에서 특정 조건에 부합하는 데이터만 조회하고 싶을 때 사용하는 것이 WHERE절 입니다.


그럼 바로 WHERE절을 사용해보도록 합시다.

먼저 job이 사원인 데이터만 조회하는 쿼리는 다음과 같습니다.


SELECT * FROM employee

WHERE job = '사원';



위의 결과와 같이 job이 '사원'인 데이터만 조회되었습니다.


그럼 같은 방법으로 salary가 500 이상인 데이터도 조회해보도록 합시다.


SELECT * FROM employee

WHERE salary >= 500;



위와 같이 salary가 500이상인 데이터만 조회되었습니다.


WHERE 절에서 사용되는 기본적인 연산자는 다음과 같습니다.


대소를 비교할 때 사용되는 >, <, >=, <= 와 같은 것들이 있으며,

같음을 나타내는 = 와 서로 다름을 나타내는 != 또는 <>이 있습니다.


그런데 여러개의 조건을 함께 사용해야 하는 경우는 어떻게 해야할까요?



2. 논리연산자(and / or)의 사용


여러개의 조건을 함께 사용해야 한다는 것은 다음과 같은 상황일 것 입니다.


'사장' 직급이 아니면서, salary가 500 이상인 데이터에 대해서 조회하시오. 또는

commission을 포함한 연봉이 5500만원 이하이거나 '사원' 직급인 데이터를 조회하시오.


이러한 경우는 어떻게 할까요?

바로 여러개의 조건을 동시에 사용하면 되는데, 이럴 때 사용하는 것이 논리 연산자 입니다.

and 논리 연산자는 좌,우측의 조건을 동시에 만족해야 할 때 사용되며,

or 논리 연산자는 좌,우측의 조건중 하나만 만족하면 될 때 사용합니다.


그럼 바로 쿼리문으로 확인해보도록 하겠습니다.

'사장' 직급이 아니면서, salary가 500 이상인 데이터에 대해서 조회하는 쿼리는 다음과 같습니다.


SELECT * FROM employee

WHERE job != '사장'

AND salary >= 500;



위와 같이 우리가 기대한 결과가 잘 나온 것을 확인할 수 있습니다.


그럼 이번에는 OR연산자를 이용해보도록 합시다.

commission을 포함한 연봉이 5500만원 이하이거나 '사원' 직급인 데이터를 조회하는 쿼리는 다음과 같습니다.


SELECT * FROM employee

WHERE (salary * 12) + isnull(commission,0) <= 5500

OR job = '사원';



위의 쿼리에서는 지난 시간에 배운 isnull() 함수를 이용하여 연봉을 계산하고 해당 값을 WHERE절 에서 그대로 사용하였습니다.

위와 같이 WHERE절에서 연산도 가능하니 참고하시기를 바랍니다.



3. BETWEEN A AND B


이번에 배워볼 것은 위와 같이 WHERE절에서 사용되는 BETWEEN A AND B 구문입니다.

만약 salary가 300이상 500이하인 데이터에 대해서 조회하려면 어떻게 해야할까요?

우리가 위에서 배운 내용대로라면, 아래와 같은 쿼리가 될 것입니다.


SELECT * FROM employee

WHERE salary >= 300

AND salary <= 500;


하지만 BETWEEN A AND B 구문을 이용하면 다음과 같이 쿼리를 작성하면 됩니다.


SELECT * FROM employee

WHERE salary BETWEEN 300 AND 500;



실제로 같은 결과를 가져오지만 이전의 쿼리보다 보다 간결하고 직관적임을 알 수 있습니다.



4. IN


마지막으로 배워볼 구문은 IN입니다.

만약 salary가 300, 400, 500, 600인 데이터를 조회하려면 어떻게 해야할까요?

이전의 학습을 기반으로 쿼리를 작성해보면 다음과 같습니다.


SELECT * FROM employee

WHERE salary = 300

OR salary = 400

OR salary = 500

OR salary = 600;


하지만 IN 구문을 이용하면 다음과 같이 쿼리를 작성할 수 있습니다.


SELECT * FROM employee

WHERE salary IN (300,400,500,600);



IN구문을 활용함으로써 OR을 통한 이전의 쿼리보다 더 간결하고 직관적임을 알 수 있습니다.



이번 포스팅에서는 WHERE 절을 이용해서 조건에 부합하는 데이터 조회방법에 대해서 알아보았습니다.

사실 WHERE절 없이 SELECT를 활용하는 경우보다는 WHERE절을 통해 원하는 데이터만 조회할 때가 더 많다고 생각됩니다. 따라서 위에 나온 쿼리문들 이외에도 다양하게 시도해보고 쿼리문을 만들어보시길 바랍니다.


블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc

안녕하세요. 문범우입니다.

이번 포스트에서는 몽고db에서 사용되는 update() 메소드와 제한자에 대해서 알아보도록 하겠습니다.



먼저 오늘 알아볼 내용에 앞서, 필요한 mock-up 데이터는 아래와 같습니다.



위의 데이터를 만드는 쿼리문은 아래와 같습니다.


gameUser 쿼리문


gameItem 쿼리문



1. 업데이트(Update)


특정 다큐먼트(document)를 수정하는 업데이트에 대해서 알아보도록 하겠습니다.

userItem에 있는 어둠의 단도라는 항목의 price를 수정해보도록 할게요.

현재 어둠의 단도의 가격은 980,000,000입니다. 해당 가격을 1,000,000,000 으로 바꿔볼게요!


mongoDB의 공식문서를 살펴보면 update메소드는 다음과 같은 구조를 가지고 있습니다.


db.COLLECTION.update(

<query>,<update>,

{

upsert: <boolean>,

multi: <boolean>,

writeConcern: <document>,

collation: <document>

}

)


구조에 있는 각각의 인자에 대한 설명은 아래와 같습니다.


Parameter

Type

Description

query

document

업데이트를 할 항목을 선택합니다. find() 함수에서 사용되는 것과 동일합니다.

update

document

선택된 document에 적용할 수정사항을 입력합니다.

upsert

boolean

Optional. (기본값: false) 만약 해당 값을 true로 설정하면, query한 document가 없을 경우 새로운 document를 추가합니다.

multi

boolean

Optional. (기본값: false) 만약 해당 값을 true로 설정하면, query에 해당하는 다수의 document를 수정합니다.

writeConcern

document

Optional. document의 write concern을 표현합니다. 기본으로 사용할 때는 생략합니다. 자세한 설명을 위해서는 메뉴얼을 참고하세요.

collation

document

Optional. Collation을 통해 사용자는 대문자 및 악센트 부호와 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다. collation은 기본적으로 다음과 같은 사항을 가지고 있습니다.

collation: {
   locale: <string>,
   caseLevel: <boolean>,
   caseFirst: <string>,
   strength: <int>,
   numericOrdering: <boolean>,
   alternate: <string>,
   maxVariable: <string>,
   backwards: <boolean>
}


위의 공식문서를 확인하여 어둠의 단도라는 item의 가격을 수정합니다.


쿼리문은 다음과 같습니다.


db.gameItem.update({name:"어둠의 단도"},{$set:{price:1000000000}});


<query>는 {name:"어둠의 단도"}로 하였습니다.

{_id:"i777"}로 해도 동일합니다.

<update>는 {$set:{price:1000000000}}으로 함으로써 price를 수정하도록 하였습니다.

$set은 제한자라고 불리는 것인데 제한자에 대한 자세한 것은 아래에서 더 살펴보도록 할게요.

아래 사진과 같이 올바른 결과를 나타냅니다.




2. 배열 데이터 추가, 삭제하기


mock-up data를 살펴보면 gameUser의 item 항목에는 배열로써 각 아이템의 _id값을 가지고 있습니다.

그렇다면 특정 유저가 아이템을 얻게되면 어떻게 표현할까요?

그리고 아이템을 잃게되면 어떻게 표현할까요?

위를 표현하기위해 배열항목에 데이터를 추가하거나 삭제하는 방법을 알아보도록 하겠습니다.


2-1. 추가하기


먼저 배열에 데이터를 추가해보도록 하겠습니다. 이 또한, 위에서 사용된 update() 함수를 사용합니다.

초보자라는 user에게 "초보자의 분노" 아이템을 추가해볼게요.

위의 document 수정에서는 $set이라는 제한자가 사용되었는데, 이번에는 $push라는 제한자를 사용합니다.

쿼리를 확인하면 다음과 같습니다.


db.gameUser.update({name:"초보자"},{$push:{item:"i004"}});


아래와 같이 올바른 결과를 나타냅니다.




2-2. 삭제하기


삭제또한, update() 함수를 사용하지만 제한자가 바뀌게 됩니다.

추가를 할땐 $push를 사용하였는데, 삭제에서는 $pull 제한자가 사용됩니다.

이번에는 장사꾼 user가 초보자의 갑옷을 버린 상황입니다.

즉, 장사꾼 user가 가진 item중 초보자의 갑옷을 삭제하도록 하겠습니다.

쿼리문은 다음과 같습니다.


db.gameUser.update({name:"장사꾼"},{$pull:{item:"i002"}});


이 또한 아래와 같이 올바른 결과를 나타냅니다.




3. 제한자


지금까지 document를 수정하고, document의 배열 항목에 데이터를 추가, 삭제하는 것을 알아보았습니다.

그런데 중간중간 '제한자'라는 개념이 등장했죠. 조금 더 구체적으로 말하면 이는 '갱신 제한자'입니다.

이번에는 갱신 제한자에 대해서 더 구체적으로 알아보도록 하겠습니다.


MongoDB에서 갱신 제한자라는 것은, 문서의 부분 갱신을 할때 매우 효율적으로 수행할 수 있도록 하는 개념입니다. document를 변경하거나 추가 또는 삭제하고, 배열과 같은 항목에 대한 연산을 하는데 사용될 수 있습니다.


그렇다면 갱신 제한자의 종류와 그 사용법에 대해서 알아보도록 하겠습니다.


갱신 제한자

설명

$set

document에서 특정 키의 값을 수정합니다. 특정 키가 존재하지 않다면 새롭게 생성합니다.

특정 키의 데이터형도 수정할 수 있습니다.

$unset

document에서 특정 키와 값을 모두 제거합니다.

$nc

배열에 사용되는 제한자로써, 지정된 키가 존재하는지 확인할 수 있습니다.

$inc

이미 존재하는 키의 값을 수정하거나, 새로운 키를 생성합니다. $set과 비슷하지만 주로 값이 자주 변경되는 값을 수정하는데 사용됩니다.

int, long, double 의 자료형에만 사용이 가능합니다.

$push

배열에 사용되는 제한자로써, 지정된 키가 존재할 때 해당 키(배열)의 끝에 요소를 추가하며 지정된 키가 존재 하지 않으면 새로운 배열을 추가합니다.

$pull

배열에 사용되는 제한자로써, 지정된 키에 대한 요소를 삭제합니다.

$addToSet

배열에 사용되는 제한자로써, 중복을 피해서 요소를 배열에 추가할 때 사용합니다. 즉, $nc와 $push를 함께 수행하는 기능과 같습니다.

$each

$addToSet과 함께 사용되는 제한자로써, 여러 개의 값을 중복되지 않게 배열에 추가합니다.

$pop

배열을 스택이나 큐처럼 활용할 수 있습니다.




블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요.

오늘은 mongoDB에서 데이터 자료형과 find함수, 쿼리연산자에 대해서 알아보도록 하겠습니다.

내용에 대한 피드백이나 궁금한 점은 언제든지 댓글을 남겨주세요 :)


1. 데이터 자료형(Datatypes)


MongoDB에는 많은 데이터 자료형을 지원합니다. 그 중 몇가지에 대해서만 알아보도록 하겠습니다.


String

 String은 데이터를 저장할때 가장 많이 사용되는 데이터 자료형 중 하나입니다. MongoDB에서 String은 반드시 UTF-8 형식만 가능합니다.

Integer

 숫자값을 저장할때 주로 사용되는 자료형입니다. Integer는 서버에 따라서 32bit 또는 64bit입니다.

Boolean

 이것은 참(true) 또는 거짓(false)를 나타내는 값을 저장하는 자료형입니다.

Double

 Double 자료형은 부동 소수점 값을 저장하는데 사용됩니다.

Min/Max keys

 이것은 BSON요소의 최저 값과 최고값을 비교하는데 사용됩니다.

Arrays

 Arrays 자료형은 배열 또는 여러 값을 하나의 키에 저장하는데 사용됩니다.

Timestamp

 해당 자료형은 문서가 수정되거나 추가될때 기록하기 편리합니다.

Object

 해당 자료형은 embedded documents에 사용됩니다.

Null

 Null 자료형은 Null 값을 저장할 떄 사용됩니다.

Symbol

 해당 자료형은 문자열(String)과 동일하게 사용됩니다. 하지만 일반적으로 특정 기호 유형을 사용하는 언어로 사용되고 있습니다.

Date

 Date 자료형은 현재의 날짜 또는 시간을 UNIX시간 형식으로 저장하는 데 사용됩니다. Date 객체를 만들어 내며 일, 월, 년을 전달하여 자신의 날짜 및 시간을 지정할 수 있습니다.

Object ID

 이것은 document의 ID를 저장하는데 사용됩니다.

Binary data

 이것은 2진수 데이터를 저장하는데 사용됩니다.

Code

 이것은 document 내부에 JavaScript 코드를 저장하는데 사용됩니다.

Regular expression

 이것은 정규 표현식을 저장하는데 사용됩니다.



2. Document 검색:: find() 함수


이번에는 Document를 검색하는 find() 함수에 대해서 알아보도록 하겠습니다.

먼저 find method에 대한 정의는 아래와 같습니다.


db.COLLLECTION-NAME.find(query,projection)


Parameter

Type

Description

query

document

Optional(선택적임).

검색시 보다 구체적인 내용을 반환받기 위해 조건을 입력. default로는 모든 값을 검색.

projection

document

Optional(선택적임).

검색후 반환 값(출력 값)을 어떤식으로 할지 결정함. default로는 모든 값을 출력. 


find는 위와 같은 구조를 가진 함수입니다. 그럼 바로 사용해볼까요?



위의 사진에서 순서대로 확인해보겠습니다.

먼저 사용할 데이터베이스를 선택하고, 어떠한 collection들이있는지 확인해보았습니다.

그리고 존재하는 firstCollection을 find()함수로 확인해보았습니다.

하나의 document가 존재하여 2개의 document를 추가하였습니다.

이후 find() 함수를 한번더 사용하였습니다.


이때, document가 한줄로 출력되서 보기 힘드신가요?

이러한 시각적 불편함을 해결하기위해 pretty() 함수가 있습니다.

함수이름대로, 보기좋게 document를 출력해주는 함수입니다.

아래 사진을 보시면 잘 이해가 가실거에요.



pretty() 함수를 사용하지 않았을떄와 사용했을떄의 차이가 보이시나요?



2-1. find() 함수 활용하기


find() 함수를 좀 더 응용해보도록 할게요.

기본적으로, collection에 있는 모든 다큐먼트를 조회하려면 어떻게 해야 할까요?

네. 맞습니다. 위에서 했던 것처럼,

db.COLLECTION-NAME.find()

를 입력하면 해당 컬렉션의 모든 document가 조회됩니다.


이제 몇가지 조건을 추가해볼게요.

위의 firstCollection을 바탕으로 하여, 성별(sex)가 남자(male)인 다큐먼트만 조회하려면 어떻게 해야할까요?

find() 함수의 정의에서 살펴본 것처럼, query parameter에 조건을 추가하면 되겠죠?


db.firstCollection.find({"sex":"male"})



한번 더 해보겠습니다.

그럼, 전공이 운동(sport)인 다큐먼트의 이름(name)을 조회하려면 어떻게 해야할까요?

네, 바로 query와 projection 두개다 적절히 조건을 추가하면 되겠습니다.


db.firstCollection.find({"major":"sport"},{"_id":false,"name":true})




3. 쿼리 연산자(Query operators)


이번에는 MongoDB에서 사용되는 쿼리 연산자(Query operators)에 대해서 살펴보겠습니다.

쿼리연산자는 위에서 알아본 find() 함수와 함께 응용되어 다양한 기능을 할 수 있습니다.

쿼리 연산자는 프로그래밍 언어에서 사용되는 비교(Comparison), 논리(Logical)등과 같은 다양한 종류의 연산자가 있습니다.

하나씩 살펴보기에 앞서, 연산자들에 대한 예제를 진행하기 위해서 기본 muck up data를 설정하겠습니다.


insert 코드는 아래와 같으며 그에 대한 muck up data를 find()함수로 확인하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
db.operatorTest.insert([
{
    "name":"John""sex":"male""major":"ECE""score":76"grade":"B"
},{
    "name":"Kai""sex":"male""major":"art""score":99"grade":"A"
},{
    "name":"Jane""sex":"female""major":"ECE""score":90"grade":"A"
},{
    "name":"Ko""sex":"male""major":"ECE""score":21"grade":"F"
},{
    "name":"Ki""sex":"female""major":"dance""score":79"grade":"B"
},{
    "name":"Bro""sex":"female""major":"art""score":68"grade":"C"
},{
    "name":"Victor""sex":"male""major":"ECE""score":49"grade":"D"
},{
    "name":"Kan""sex":"female""major":"art""score":61"grade":"C"
}
])
cs





3-1. 비교(Comparison)


연산자

설명(Description)

$eq

Matches values that equal to a specified value.

주어진 값과 동일한 값

$gt

Matches values that are greater than a specified value.

주어진 값보다 더 큰 값

$gte

Matches values that are greater than or equal to a specified value.

주어진 값보다 크거나 같은 값

$lt

Matches values that are than a specified value.

주어진 값보다 더 작은 값

$lte

Matches values that are less than or equal to a specified value.

주어진 값보다 작거나 같은 값

$ne

Matches all values that are not equal to a specified value.

주어진 값과 동일하지 않은 값

$in

Matches any of the values specified in an array.

주어진 배열에 속하는 어떤 값

$nin

Matches none of the values specified in an array.

주어진 배열에 속하지 않는 어떤 값


예제)

A) score의 값이 70이하이고, 45초과를 하는 document를 조회하여라.


query & result



B) grade가 [A,B,C,D]에 속하지 않는 document를 조회하여라.


query & result



C) major가 art인 document를 조회하여라.


query & result



3-2. 논리(Logical)


연산자

설명(Description)

$or

Joins query clauses with a logical OR returns all documents that match the conditions of either clause.

논리적 OR과 같은 의미로써, 주어진 조건 중 하나라도 true일때 true를 반환합니다.

$and

Joins query clauses with a logical AND returns all documents that match the conditions of both clauses.

논리적 AND와 같은 의미로써, 주어진 조건 중 모든 조건이 true일때 true를 반환합니다.

$not

Inverts the effect of a query expression and returns documents that do not match the query expression.

주어진 조건에 대해 반대 논리를 반환하는 것으로써, 주어진 조건이 false일때 true를 반환합니다.

$nor

Joins query clauses with a logical NOR returns all documents that fail to match both clauses.

주어진 조건 중 모든 조건이 false일때 true를 반환합니다.


예제)

A) 성별이 남자(male)이고 score가 50이하인 document를 조회하여라.


query & result



B) 전공(major)가 ECE가 아니고 score가 80미만이 아닌 document를 조회하여라.


query & result



C) 전공(major)가 ECE가 아니거나 score가 80미만이 아닌 document를 조회하여라.


query & result



3-3. 요소(Element)


연산자

설명(Description)

$exists

Matches documents that have the specified field.

주어진 필드를 가진 documents를 조회합니다.

$type

Selects documents if a field is of the specified type.

field가 지정된 유형인 경우 해당 documents를 선택합니다.



3-4. 평가(Evaluation)


연산자

설명(Description)

$mod

Performs a modulo operation on the value of a field and selects documents with a specified result.

field 값에 대한 modulo 연산을 수행하고 해당 결과가 있는 documents를 선택합니다.

$regex

Selects documents where values match a specified regular expression.

정규 표현식(regular expression)과 일치하는 documents를 선택합니다.

$text

Performs text search.

텍스트 검색을 수행합니다.

$where

Matches documents that satisfy a JavaScript expression.

JavaScript 표현식에 만족하는 documents를 조회합니다.



3-5. 배열(Array)


연산자

설명(Description)

$all

Matches arrays that contain all elements specified in the query.

query에 지정된 모든 요소를 포함하는 배열을 찾습니다.

$elemMatch

Selects documents if element in the array field matches all the specified $elemMatch conditions.

배열 field의 요소가 지정된 $elemMatch의 조건과 모두 일치하는 documents를 선택합니다.

$size

Selects documents if the array field is a specified size.

배열 field가 지정된 크기인 경우의 documents를 선택합니다.



네, 이렇게 해서 MongoDB에서 데이터 자료형과, find() 함수, 다양한 연산자에 대해서 알아보았습니다.

내용에 대한 피드백이나 궁금한 점은 언제나 댓글을 이용해주세요 :)

블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

오늘은 MySQL에서 변수를 이용하는 방법에 대해 알아보도록 하겠습니다.

이해를 돕기 위해 예제를 가지고 진행하는 방식으로 해볼게요.

예제에서는 delimiter에 대한 사용이 나옵니다.

delimiter에 대해서 잘 모르신다면 지난 포스팅을 통해 확인하시길 바랍니다.


1. 예제 환경 구성


오늘은 아래와 같은 테이블에서 시작합니다.



테이블을 만들기 위한 코드는 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE TABLE person_1(
_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32NOT NULL,
job VARCHAR(64),
height INT NOT NULL,
english INT NOT NULL
);
 
INSERT INTO person_1 (name,job,height,english)
VALUES ('김철수',NULL,173,84),
('최고야','student',189,99),
('박사장','ceo',162,76),
('이세상',NULL,159,12),
('김영희',NULL,182,35),
('오감자','snack',139,3),
('수박바','student',155,65);
cs


위의 테이블을 가지고 진행을 해보도록 하겠습니다.

오늘의 목표는, 각 사람이 가진 영어점수를 바탕으로 순위를 매기는 것 입니다.

단순히 출력할때 순위가 보이도록 하는 것이 아니라, 새로운 속성을 추가하여 각각에 대한 순위를 저장하도록 하겠습니다.


2. MySQL 사용자 정의 변수


MySQL 에서는 사용자 정의 변수를 이용할 수 있습니다.

또한 당연히, 선언한 변수를 쿼리문에서 사용할 수 있습니다.

만약 var라는 이름의 변수를 선언하고 싶다면 아래와 같이 쿼리를 입력하면 됩니다.


1
SET @var = 1;
cs


위의 쿼리와 같이 SET @(변수명) 을 통해 변수를 선언합니다.

그리고 변수를 사용할때는 @(변수명) 을 통해서 변수를 사용하면 됩니다.


3. 순위 속성을 추가하고 순위 매기기


그럼 위에서 말한 것과 같이 새로운 '순위' 속성을 추가하고 각각에 대한 영어점수의 순위를 매겨보도록 하겠습니다.

먼저 rank 속성을 추가합니다.


쿼리문은 아래와 같습니다.


1
ALTER TABLE person_1 add column rank INT;
cs


그리고 이제 지난 포스팅에서 학습한 delimiter와 사용자 정의 변수를 이용해보도록 하겠습니다.

먼저 전체 쿼리문은 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
SET @rank = 1;
 
DELIMITER //
CREATE TRIGGER person_update
AFTER UPDATE ON person_1
FOR EACH ROW BEGIN
SET @rank=@rank+1;
END //
DELIMITER ;
 
UPDATE person_1 SET rank=@rank ORDER BY english DESC;
cs


1번 라인을 보시면 rank 라는 변수를 1로 선언과 동시에 초기화 하였습니다.


그리고 이어서 DELIMITER를 사용하여 트리거를 만듭니다.

트리거는 person_1 테이블이 update될 때마다 작동되며 6번 라인을 통해 각 행마다 적용되도록 설정하였습니다.

트리거 내용으로는, rank 변수의 값을 1을 증가 시키는 내용입니다.

이렇게 트리거를 만들고 다시 DELIMITER를 수정합니다.


그리고 11번 라인에서와 같이 person_1테이블의 새로만든 속성, rank 속성에 rank변수 값을 입력합니다.

이때 테이블은 english 점수의 내림차순으로 출력된 상태입니다.


이렇게 쿼리를 입력하고 테이블을 확인하면 아래와 같습니다.



어떻게 해서 이런 결과가 나올까요?

다시 쿼리문을 확인해보면, 트리거는 각 행마다 진행이 됩니다.

즉 테이블이 영어점수의 내림차순으로 출력된 상태라면 제일 첫번째 행은 가장 높은 점수를 가진사람일 것입니다.

그럼 UPDATE 문에 의해서 그 사람의 rank는 1로 입력이 되고 이후 rank의 값은 트리거에 의해 1이 증가합니다.

그리고 이어서 두번째 사람의 rank에는 변수의 값이 1이 증가되었기 때문에 2가 저장되고,

그 다음사람은 3이 저장되는 방식입니다.




사용자 정의 변수에 대해서 간략하게 알아보고 예제를 통해 사용해보았습니다.

이후 사용자 정의 변수에 대해서는 사용이 될 때마다 추가적인 설명을 붙이도록 하겠습니다.

블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번에는 지난 포스팅에 이어서 MySQL의 'SELECT 조건에 따른 데이터 검색'에 대한 명령어를 알아보겠습니다.




SELECT (속성1, 속성2, … ) FROM (테이블명) WHERE (조건식);

(조건식)에 의해 해당하는 행을 선택하고 (속성1, 속성2, … )에 의해 열을 선택합니다.

 

SELECT * FROM (테이블명);

WHERE 조건문이 없으므로 모든 행을 선택하고, *(: 모든)을 통해 모든 열을 선택합니다.

(테이블명)의 이름을 가진 테이블을 확인하는 명령어입니다.

 

SELECT * FROM (테이블명) WHERE (조건1) AND (조건2);

(테이블명)의 테이블에서 (조건1) (조건2)를 모두 만족하는 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) BETWEEN (1) AND (2);

(테이블명)의 테이블에서 (속성1)의 값이 (1)(2) 사이인 행의 모든 열을 선택합니다.

 

          - 참고

           아래 두 명령어를 비교합니다.

           SELECT * FROM (테이블명) WHERE age > 19 AND age < 30;

           SELECT * FROM (테이블명) WHERE age BETWEEN 19 AND 30;

           두 명령어를 통한 결과 값은 같지만 성능은 BETWEEN을 사용한 명령어가 더 좋습니다.

            

           단순히 AND만 사용한 첫번째 쿼리는

           전체 데이터에서 age19보다 큰 값과 30보다 작은 데이터를 각각 구해 이들의 교집합 값을 구하는 연산이며

           BETWEEN을 사용한 두번째 쿼리는

           age라는 속성에서 19라는 값부터 시작하여 30이라는 값보다 작은 값을 찾는 연산이기 때문입니다.

 

SELECT * FROM (테이블명) WHERE (조건1) OR (조건2);

(테이블명)의 테이블에서 (조건1) (조건2) 중 어떤 하나라도 만족하는 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) IN (조건1, 조건2, … );

(테이블명)의 테이블에서 (속성1)의 값이 (조건1)이거나 (조건2) 인 행의 모든 열을 선택합니다.

 

          - 참고

           IN을 사용한 구문 또한 BETWEEN을 사용한 구문과 같이 OR보다 성능이 좋습니다.

           아래 두 쿼리를 비교합니다.

 SELECT * FROM (테이블명) WHERE age = 19 OR age = 20 OR age = 21;

           SELECT * FROM (테이블명) WHERE age IN (19,20,21);

           두 쿼리 모두 같은 결과를 출력하지만 IN을 사용한 두번째 쿼리가 성능이 좋습니다.

 

          - 참고

          AND 연산이 OR 연산보다 우선순위가 높습니다.

          , age19 또는 20인 열과 birth1998 또는 1999인 행의 모든 열을 선택하려면

          SELECT * FROM (테이블명) WHERE age = 19 OR age = 20 AND birth = 1998 OR birth = 1999;

가 아닌

SELECT * FROM (테이블명) WHERE (age = 19 OR age = 20)AND(birth = 1998 OR birth = 1999);

를 입력해야 합니다.

 

SELECT * FROM (테이블명) WHERE NOT (조건1);

(테이블명)의 테이블에서 (조건1)을 만족하지 않는 행의 모든 열을 선택합니다.


SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘A_’;

(테이블명)의 테이블에서 (속성1) ‘A+1글자값을 가진 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘A__’;

(테이블명)의 테이블에서 (속성1) ‘A+2글자값을 가진 행의 모든 열을 선택합니다.


          - 참고

          위의 _ 관련 쿼리의 예제입니다.

          


SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘A%’;

(테이블명)의 테이블에서 (속성1) ‘A’로 시작하는 값을 가진 행의 모든 열을 선택합니다.


SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘%A’;

(테이블명)의 테이블에서 (속성1) ‘A’로 끝나는 값을 가진 행의 모든 열을 선택합니다.

 

SELECT * FROM (테이블명) WHERE (속성1) LIKE ‘%A%’;

(테이블명)의 테이블에서 (속성1) ‘A’를 포함하는 값을 가진 행의 모든 열을 선택합니다.

 

          - 참고

             위의 % 관련 쿼리의 예제입니다.

 


SELECT * FROM (테이블명) ORDER BY (속성1) (순서);

(테이블명)이란 테이블에서 (속성1)(순서)에 따라 모든 열을 출력합니다.

이따 (순서)에는 DESC(내림차순) 또는 ASC(오름차순)을 입력하며 생략했을시의 default 값은 ASC(오름차순) 입니다.

 

SELECT (속성1) AS ‘별명1’, (속성2) AS ‘별명2’ FROM (테이블명);

(테이블명)이란 테이블에서 (속성1)은 별명1이란 이름으로, (속성2)는 별명2라는 이름으로 두개의 열을 출력한다.

 

SELECT DISTINCT (속성1), (속성2), … FROM (테이블명);

(테이블명)이란 테이블에서 (속성1), (속성2), … 를 선택하는데 이때 중복되는 값은 제외합니다.

 

          - 참고

             DISTINCT 관련 쿼리를 예제를 통해 확인합니다. 두 명령어에 따른 출력 값의 차이를 확인하세요.


             기본테이블

 


DISTINCT 쿼리에 따른 차이


 


이렇게 해서 MySQL에서 SELECT 조건에 따른 데이터 검색에 관한 명령어를 알아보았습니다.

다음 포스팅에서부턴 특정 예제를 기준으로 하여 명령어를 알아보도록 하겠습니다.

피드백이나 문의사항은 댓글 및 이메일(doorbw@outlook.com)을 이용해주세요 :)

 

 

블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc


안녕하세요.

데이터베이스를 학교에서 공부중에 있는데 MySQL을 사용하여 수업을 하고 있습니다.

따라서 MySQL에서 사용되는 명령어들을 정리할겸 포스팅을 진행하려 합니다.

각각의 명령어들을 최대한 순서(?)에 맞춰서 의미들을 설명하려하는데

부족한 점이 있거나 추가적인 명령어들이 있다면 덧글로 피드백 해주세요 :)


이번 포스팅에서 공부해볼 내용은 'Database 및 Table 생성 / 확인 / 제거 / 수정' 에 대한 명령어 입니다.

다음 포스팅에서는 '조건에 따른 데이터 검색'에 대한 명령어를 알아보겠습니다.


CREATE DATABASE 데이터베이스명 default CHARACTER SET UTF8;

(데이터베이스명)이라는 데이터 베이스를 생성하고 한글을 사용할 수 있는 UTF8로 문자열을 저장

 

GRANT ALL PRIVILEGES ON (데이터베이스명).* TO (사용자)@localhost INDENTIFIED BY ‘(비밀번호)’;

GRANT는 사용자에게 데이터베이스의 사용권한을 적용하는 구문입니다.

ALL PRIVILEGES 는 데이터베이스에 대한 모든 권한을 의미합니다. (DB 삭제 또한 가능)

ON (데이터베이스명).* 은 권한 대상 데이터베이스의 테이블을 설정합니다. .* 를 통해 모든 테이블을 의미합니다.

TO (사용자)@localhost 는 사용 권한을 받는 사용자를 지정합니다. 없는 유저라면 새롭게 생성하며 localhost는 말 그대로 로컬에서만 연결 가능함을 뜻합니다.

(localhost가 아닌 외부에서 접근하려고 한다면 접근권한을 따로 설정해 주어야 합니다.)

INDENTIFIED BY ‘(비밀번호)’ 는 사용자의 비밀번호를 설정합니다.

 

SHOW DATABASES;

데이터베이스들의 목록을 보여주는 명령어

 

USE (데이터베이스명)

(데이터베이스명)이라는 이름의 데이터베이스를 사용

 

DROP DATABASE (데이터베이스명);

(데이터베이스명)이라는 이름의 데이터베이스를 제거합니다.


CREATE TABLE (테이블명)(

_id INT PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(32) NOT NULL,

job VARCHAR(64) DEFAULT ‘student’,

phone VARCHAR(12)

) ENGINE=INNODB;

(테이블명)이라는 이름을 가진 테이블을 생성합니다.

( ) 내부에 속성을 입력합니다. 각각에 대한 설명은 아래와 같습니다.

_id 란 이름의 칼럼을 추가하며, 데이터 타입은 INT 입니다. 해당 칼럼을 PRIMARY KEY(기본 키)로 설정합니다. AUTO_INCREMENT를 통해 자동으로 인덱스를 증가시킵니다.

name 이란 이름의 칼럼을 추가하며, NULL을 허락하지 않으므로 자료를 입력할 때 항상 값을 넣어줘야 합니다.

job 이란 이름의 칼럼을 추가하며, DEFAULT(아무런 값을 입력하지 않았을 때의 값) ‘student’로 설정합니다.

phone 이란 이름의 칼럼을 추가합니다.

ENGINE = INNODBMySQL의 저장구조를 설정합니다.(생략가능)

 

DESCRIBE (테이블명);

(테이블명)이라는 이라는 테이블의 구조를 확인합니다. 줄여서 DESC (테이블명); 또한 가능합니다.

 

-      참고

Field = 열 이름

Type = 해당 열의 자료형 ex) int(11) '11자리의 정수값을 저장할 수 있는 자료형'

Null = NULL 값을 허용할 것인지 아닌지를 나타내는 제약사항으로 YES로 지정하면 NULL 값을 허용

Key = 해당 열이 ''로 지정되어 있는지 나타냄.

Default = 그 열에 주어진 '기본값' , 생략했을 경우 적용되는 값

자료형

INTEGER = 정수값을 저장할 수 있는 자료형

CHAR = 문자열을 저장할 수 있는 자료형. 열의 최대 길이를 지정해야 함 => 고정 길이 문자열

VARCHAR = 문자열을 저장할 수 있는 자료형.데이터크기에 맞춰 저장공간의 크기도 변경됨 =>가변 길이 문자열

DATE = 날짜값을 저장할 수 있는 자료형. 연월일

TIME = 시간을 저장할 수 있는 자료형. 시분초

 

SHOW TABLES;

데이터베이스 안의 사용 가능한 테이블 목록을 보여주는 명령어

 

INSERT INTO (테이블명) (칼럼1, 칼럼2, … ) VALUES (칼럼1의 값, 칼럼2의 값, … );

(테이블명)이라는 테이블의 (칼럼1, 칼럼2, … ) 맞춰서 (칼럼1의 값, 칼럼2의 값, … )을 넣습니다.


SELECT (칼럼1, 칼럼2, … ) FROM (테이블명);

(테이블명) 이라는 테이블에서 (칼럼1, 칼럼2, … )의 값을 읽어옵니다.

 

SELECT * FROM (테이블명);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는 명령어

 

-      참고

숫자로 구성된 데이터      =  수치형 데이터(오른쪽 정렬)

문자로 구성된 데이터      =  문자열형 데이터(왼쪽 정렬)

날짜와 시각을 나타내는 데이터 =  날짜시간형 데이터(왼쪽 정렬)

열은 하나의 자료형만 가질 수 있고, 수치형의 열에 문자형의 데이터를 저장할 수는 없다.

값이 없는 데이터 = NULL

 

SELECT * FROM (테이블명) ORDER BY (칼럼 명);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (칼럼 명)을 기준으로 정렬하여 읽어옵니다.

 

SELECT * FROM (테이블명) WHERE (조건);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (조건)을 만족하는 행을 읽어옵니다.

 

SELECT * FROM (테이블명) WHERE (칼럼 명) LIKE ‘2017%’;

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (칼럼 명)에서 값이 2017로 시작하는 모든 값을 읽어옵니다.

 

SELECT * FROM (테이블명) WHERE (칼럼 1) <> (칼럼 2);

(테이블명) 이라는 테이블에서 (*: 모든)데이터를 읽어오는데, (칼럼 1) (칼럼 2)가 같지 않은 행만 읽어옵니다.

( <>!= 와 같은 의미 입니다.)

 

ALTER TABLE (테이블명) ~ ;

(테이블명)이라는 이름의 테이블을 대상으로 테이블의 이름을 변경(RENAME)하거나 테이블에 칼럼(속성)을 추가(ADD)하거나 테이블의 칼럼(속성)을 변경(CHANGE, MODIFY)하거나 테이블의 칼럼(속성)을 제거(DROP)하는 명령을 내릴 수 있습니다.

 

ALTER TABLE (테이블명) RENAME TO (바꿀 이름);

(테이블명)이라는 테이블의 이름을 (바꿀 이름)이라는 이름으로 바꿉니다.

 

ALTER TABLE (테이블명)

ADD COLUMN (새로운 속성) INT NOT NULL AFTER (기존의 속성_1),

ADD PRIMARY KEY (기존의 속성_2);

(테이블명)이라는 테이블에 (새로운 속성)이라는 이름의 속성을 (기존의 속성_1)의 뒤에 추가합니다.

이때 (새로운 속성) INT형 자료를 가지며 NULL을 허용하지 않습니다.(NOT NULL)

또한 (기존의 속성_2)PRIMARY KEY(기본 키)로 변경합니다.

 

ALTER TABLE (테이블명)

MODIFY COLUMN (속성 이름) (변경할 타입);

(테이블명)이라는 테이블의 (속성 이름)이라는 속성의 타입을 (변경할 타입)으로 바꿉니다.

 

ALER TABLE (테이블명)

CHANGE COLUMN (속성 이름) (변경할 속성 이름) (변경할 타입);

(테이블명)이라는 테이블의 (속성 이름)이라는 속성의 이름을 (변경할 속성 이름)으로 바꾸고 타입을 (변경할 타입)으로 바꿉니다.

 

ALTER TABLE (테이블명)

DROP COLUMN (속성 이름),

DROP PRIMARY KEY;

(테이블명)이라는 테이블에서 (속성 이름)이라는 이름의 속성을 제거합니다.

또한 PRIMARY KEY(기본 키)를 제거합니다.


UPDATE (테이블명)

SET (속성 이름) = (바꿀 값)

WHERE (조건: ex. Age > 20);

(테이블명)이라는 테이블에서 WHERE 구문의 조건에 맞는 레코드의 (속성 이름) 값을 (바꿀 값)으로 변경합니다.

- 참고

좌측의 테이블이 있다고 했을 때, 현재 adult 속성의 값을 보면 제대로 맞지 않습니다.

이를 수정하기 위해서 UPDATE 구문을 사용하겠습니다.

 

사용된 명령어는 아래와 같습니다.

UPDATE updateTest

SET adult = ‘Yes’ WHERE age > 19;

 

UPDATE updateTest

SET adult = ‘No’ WHERE age <= 19;

 

결과는 아래 사진과 같습니다.

 


DELETE FROM (테이블명) WHERE _id = 3;

(테이블명)이라는 이름의 테이블에서 _id = 3인 데이터를 삭제합니다.

WHERE 구문을 입력하지 않으면 테이블의 모든 데이터가 제거됩니다.

 

DROP TABLE (테이블명);

(테이블명)이라는 이름의 TABLE을 제거합니다. (DELETE는 데이터만 제거하는 것이고 DROP는 테이블 자체를 제거하는 것)

 

TRUNCATE TABLE (테이블명);

(테이블명)이라는 이름의 테이블의 모든 데이터를 삭제합니다.

 

           - 참고

           DELETE 명령은 데이터를 순차적으로 삭제합니다.

           TRUNCATE 명령은 테이블 자체를 삭제하고 같은 이름의 테이블을 새로 생성합니다.

           (테이블을 DROPCREATE 하는 명령어입니다.)

           따라서, 모든 데이터를 삭제할 때 DELETE 명령보다 TRUNCATE 명령이 처리속도가 빠르지만

TRUNCATE 명령은 데이터의 복구가 불가능합니다.


내용에 대한 피드백 및 궁금한 점은 댓글 및 이메일(doorbw@outlook.com) 으로 말씀해주세요 :)

다음 포스팅에서는 '조건에 따른 데이터 검색'에 대한 명령어를 알아보겠습니다.

블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc



안녕하세요. 문범우입니다.

오늘은 mongoDB의 database, collection, document 들에 대해서 알아보겠습니다.

기본적인 개념들은 지난 포스트를 참고해주시고, 오늘부터는 직접적으로 생성하고 제거하는 등의 활동을 해볼게요.



지난 포스트에서 알아본 듯이 mongoDB는 아래와 같은 architecture를 가지고 있습니다.


Database_1

Collection_1

Documents_1

 

“_id” : “~~~~~~~~~~~~”,

“name” : “홍길동”,

“age” : “30”,

. . .

 

Documents_2

. . .

 

Documents_3

. . .

. . .


 

Collection_2

. . .


Database의 내부에 Collection, 그리고 Collection 내부에 Document가 존재합니다.

이번 포스팅에서는 최종적으로 Documents 를 생성하여 우리가 원하는 key와 value를 저장해보도록 하겠습니다.

물론 그러기 위해서는 아래와 같은 과정이 필요합니다.


Database 생성 -> Collection 생성 -> Documents 생성


그리고 각각을 제거해보는 것까지 함께 해보도록 하겠습니다.


Database 생성-> Collection 생성 -> Documents 생성 -> Documents 제거 -> Collection 제거 -> Database 제거




1. Database 생성

먼저 mongoDB의 server를 키고, mongoDB에 들어갑니다.

그리고 show dbs 명령어를 통해 현재 만들어진 database를 확인할 수 있습니다.



위의 사진과 같이 아무것도 뜨지 않는다는 것은 내가 만든 데이터베이스가 없거나

만든 데이터베이스 내부에 한개 이상의 Document가 존재하지 않는다는 것 입니다.

즉, 데이터베이스가 만들어져 있더라도 해당 데이터베이스 내부에 Documents가 하나도 없다면 리스트에 보이지 않습니다.

이때, 자신이 사용중인 데이터베이스를 확인하기 위해서는 db 명령어를 입력합니다.


현재 저는 test라는 database를 사용하고 있네요.

이제 새롭게 database를 생성해보고 해당 database로 진행해보겠습니다.



use newDatabase 명령어를 통해 newDatabase라는 이름을 가진 database를 새롭게 만듭니다.

(이때 만약 해당 이름을 가진 데이터베이스가 존재한다면

새롭게 만들어지지 않고 기존에 있던 데이터베이스를 사용하게 됩니다.)

db 명령어를 통해서 사용중인 database가 바뀌었음을 확인할 수 있습니다.



2. Collection 생성

이번에는 collection을 생성해보겠습니다.

collection을 생성하기 위해서는 db.createCollection(name,[options]) 이라는 명령어를 사용합니다.

이때 name은 string Type으로써, collection의 이름을 말하며 options는 document Type으로써 선택적인 매개변수입니다.

공식문서를 통해 확인해보시고 필요한 항목을 사용하시면 됩니다. collection 이름은 firstCollection 으로 만들어보겠습니다.



지금까지 만들어진 collection을 확인하기 위해서는 show collections 명령어를 통해서 가능합니다.




3. Document 추가

Document 는 함수 자체에서 insert로 명시되어 있기에 '생성'이라는 말 대신 '추가'라는 말을 사용하였습니다.

새로운 Document를 추가하기 위해선 어떤 collection에 추가할지도 함께 고려해야합니다.

즉, 명령어에는 collection의 이름과 추가될 document의 내용이 들어갑니다.

db.COLLECTION.insert([{document1},{document2}, ... ]) 가 COLLECTION 이라는 이름을 가진 collection에 새로운 document를 추가하는 명령어 입니다.

해당 명령어를 통해 이름, 성별, 전공을 가진 document를 2개 추가해 보도록 하겠습니다.



그리고 db.COLLECTION.find() 을 통해 현재까지 추가된 document를 확인합니다.





4. document 제거

document를 제거하기 위해서는 db.COLLECTION.remove(<query>,<justOne>) 함수를 사용합니다.

db.COLLECTION.remove(<query>,<justOne>)에 대한 공식문서의 설명은 아래와 같습니다.



즉, query는 삭제할 document의 기준, 조건을 말합니다. 만약 query를 비워둔다면 모든 documents 가 해당되니 유의하세요.

justOne 은 한개만 지울 것인지에 대한 변수입니다.

default로 false값을 가지며, 딱 하나의 document만 지울때는 true로 설정하면 됩니다.


저는 3번에서 입력한 document 중 pika라는 이름을 가진 document 하나만 제거해보도록 하겠습니다.



document 하나가 올바르게 지워진 것을 알 수 있습니다.



5. Collection 삭제

현재 사용하고 있는 database의 collection을 보려면, show collections 라는 명령어를 사용하면 된다고 말하였습니다.

한번 더 확인해보겠습니다.


firstCollection 이라는 collection 하나만 존재하므로 하나를 더 생성합니다.



다시 secondCollection을 지워보도록 하겠습니다.

collection을 지우는 명령어는 db.COLLECTION.drop() 입니다.




6. Database 제거

현재 제가 만들어놓은 database의 항목을 확인해보기 위해 show dbs 명령어를 입력합니다.

제거할 database를 임시로 만들기 위하여 temp 라는 database를 만듭니다.



하지만 use temp 명령어를 입력하여도 temp라는 database는 하나이상의 document를 가지고 있지 않기 때문에

show dbs 에서 리스트에 보이지 않습니다. 따라서 빠르게 document를 추가해줍니다.

이때 따로 collection을 미리 생성하지 않아도 아래 명령어가 가능합니다.

db.tempCollection.insert({"name":"jone"})




이제 사용하지 않는 temp라는 database를 제거하기 위해 해당 database를

use DATABASE_NAME 을 통해 선택하고, db.dropDatabase() 함수를 사용하여 제거합니다.




이렇게


Database 생성-> Collection 생성 -> Documents 생성 -> Documents 제거 -> Collection 제거 -> Database 제거


순서대로 진행하였습니다.


마지막으로 각각에 대한 명령어를 정리해볼게요 !



정리


 

생 성 (추 가)

확 인

제 거 (삭 제)

Database

use DATABASE

show dbs

db.dropDatabase()

Collection

db.createCOLLECTION(name,[options])

show collections

db.COLLECTION.drop()

Document

db.COLLECTION.insert({do1},{do2}, …)

db.COLLECTION.find()

db.COLLECTION.remove(<query>,<justOne>)



오늘은 Database, Collection, Document 를 직접 생성하고 확인하고 제거해보았습니다.

다음엔 입력한 데이터를 이용한 실습을 진행해보겠습니다.

문의사항은 덧글이나 이메일(doorbw@outlook.com)을 이용해주세요 :)

블로그 이미지

Tigercow.Door

Web Programming / Back-end / Database / AI / Algorithm / DeepLearning / etc