<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>so-kr.log</title>
        <link>https://velog.io/</link>
        <description>The ultimate goal is to be a Data Scientist.</description>
        <lastBuildDate>Fri, 21 Oct 2022 17:07:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>so-kr.log</title>
            <url>https://velog.velcdn.com/images/so-kr/profile/4bdcc949-0d32-4b2d-a5ca-85ddb2df023a/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. so-kr.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/so-kr" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[MySQL_프로그래머스-6]]></title>
            <link>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-6</link>
            <guid>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-6</guid>
            <pubDate>Fri, 21 Oct 2022 17:07:53 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚩 프로그래머스(programmers)에서 제공하는 SQL 문제풀기
🚩 String, Date</p>
</blockquote>
<h2 id="📌-level-2">📌 Level 2</h2>
<h3 id="🟩-이름에-el이-들어가는-동물-찾기">🟩 이름에 el이 들어가는 동물 찾기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59047">https://school.programmers.co.kr/learn/courses/30/lessons/59047</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
  WHERE ANIMAL_TYPE=&#39;Dog&#39; AND NAME LIKE &#39;%EL%&#39;
  ORDER BY NAME ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 개의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 할머니가 기르던 개(<code>ANIMAL_TYPE=&#39;Dog&#39;</code>)는 이름에 &#39;el&#39;(<code>NAME LIKE &#39;%EL%&#39;</code>)이 들어가므로 해당 조건을 <code>WHERE 조건</code>절로 추가한다. 또한 <code>ORDER BY</code>절을 사용하여 이름(<code>NAME</code>) 순으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-datetime에서-date로-형-변환">🟩 DATETIME에서 DATE로 형 변환</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59414">https://school.programmers.co.kr/learn/courses/30/lessons/59414</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME, &#39;%Y-%m-%d&#39;) AS 날짜
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 각 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>), 들어온 날짜(<code>날짜</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 들어온 날짜는 시각(시-분-초)을 제외한 날짜(년-월-일,<code>&#39;%Y-%m-%d&#39;</code>)만 보여주기 위해 <code>DATE_FORMAT(date, format)</code>함수를 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 아이디(<code>ANIMAL_ID</code>) 순으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-중성화-여부-파악하기">🟩 중성화 여부 파악하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59409">https://school.programmers.co.kr/learn/courses/30/lessons/59409</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME, 
CASE WHEN SEX_UPON_INTAKE LIKE &#39;Intact%&#39; THEN &#39;X&#39; ELSE &#39;O&#39; END AS 중성화
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>), 중성화 여부(<code>중성화</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 중성화된 동물은 <code>SEX_UPON_INTAKE</code> 컬럼에 <code>&#39;Neutered&#39;</code> 또는 <code>&#39;Spayed&#39;</code>라는 단어가 들어있기 때문에 중성화 여부는 <code>CASE~END</code>절로 조건문을 작성한다. 또한 <code>ORDER BY</code>절을 사용하여 아이디(<code>ANIMAL_ID</code>) 순으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-루시와-엘라-찾기">🟩 루시와 엘라 찾기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59046">https://school.programmers.co.kr/learn/courses/30/lessons/59046</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
  FROM ANIMAL_INS
  WHERE NAME IN (&#39;Lucy&#39;, &#39;Ella&#39;, &#39;Pickle&#39;, &#39;Rogan&#39;, &#39;Sabrina&#39;, &#39;Mitty&#39;)
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>), 성별 및 중성화 여부(<code>SEX_UPON_INTAKE</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 동물 보호소에 들어온 동물 중 이름이 &#39;Lucy&#39;, &#39;Ella&#39;, &#39;Pickle&#39;, &#39;Rogan&#39;, &#39;Sabrina&#39;, &#39;Mitty&#39;인 동물(<code>NAME IN (&#39;Lucy&#39;, &#39;Ella&#39;, &#39;Pickle&#39;, &#39;Rogan&#39;, &#39;Sabrina&#39;, &#39;Mitty&#39;)</code>) 조건을 <code>WHERE 조건</code>절로 추가한다. 또한 <code>ORDER BY</code>절을 사용하여 아이디(<code>ANIMAL_ID</code>) 순으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-카테고리-별-상품-개수-구하기">🟩 카테고리 별 상품 개수 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131529">https://school.programmers.co.kr/learn/courses/30/lessons/131529</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT LEFT(PRODUCT_CODE, 2) AS CATEGORY, COUNT(*) AS PRODUCTS
  FROM PRODUCT
  GROUP BY CATEGORY
  ORDER BY CATEGORY ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>PRODUCT</code> 테이블에서 상품 카테고리 코드(PRODUCT_CODE 앞 2자리,<code>CATEGORY</code>) 별 상품 개수(<code>PRODUCTS</code>)를 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다. PRODUCT_CODE 앞 2자리는 <code>LEFT(문자열, 길이)</code> 함수를 사용하여 문자열의 일부를 추출하고, 상품 카테고리 코드(<code>CATEGORY</code>)별 상품 개수를 구하기 위해 <code>GROUP BY</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 상품 카테고리 코드(<code>CATEGORY</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<hr>
<h2 id="📌-level-3">📌 Level 3</h2>
<h3 id="🟩-오랜-기간-보호한-동물2">🟩 오랜 기간 보호한 동물(2)</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59411">https://school.programmers.co.kr/learn/courses/30/lessons/59411</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT O.ANIMAL_ID, O.NAME
  FROM ANIMAL_INS I
  RIGHT OUTER JOIN ANIMAL_OUTS O
  ON I.ANIMAL_ID=O.ANIMAL_ID
  ORDER BY DATEDIFF(O.DATETIME, I.DATETIME) DESC
  LIMIT 2;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블과 <code>ANIMAL_OUTS</code> 테이블에서 입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 두 테이블을 동물의 아이디(<code>ANIMAL_ID</code>)로 외부 조인(<code>OUTER JOIN</code>)한다. <code>ORDER BY</code>절을 사용하여 보호 기간이 긴 순으로 정렬하기 위해 입양일(<code>O.DATETIME</code>)과 보호 시작일(<code>I.DATETIME</code>) 두 날짜의 차이를 <code>DATEDIFF(날짜1, 날짜2)</code>함수로 계산하여 내림차순(<code>DESC</code>) 정렬하고, <code>LIMIT 숫자</code>로 보호 기간이 가장 긴 동물 두 마리를 조회한다.</p>
<h3 id="🟩-조건별로-분류하여-주문상태-출력하기">🟩 조건별로 분류하여 주문상태 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131113">https://school.programmers.co.kr/learn/courses/30/lessons/131113</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ORDER_ID, PRODUCT_ID, DATE_FORMAT(OUT_DATE, &#39;%Y-%m-%d&#39;) AS OUT_DATE,
CASE WHEN OUT_DATE IS NULL THEN &#39;출고미정&#39; WHEN DATE_FORMAT(OUT_DATE, &#39;%m-%d&#39;) &gt; &#39;05-01&#39; THEN &#39;출고대기&#39; ELSE &#39;출고완료&#39; END AS 출고여부
  FROM FOOD_ORDER
  ORDER BY ORDER_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>FOOD_ORDER</code> 테이블에서 주문 ID(<code>ORDER_ID</code>), 제품 ID(<code>PRODUCT_ID</code>), 출고일자(<code>OUT_DATE</code>), 출고여부(<code>출고여부</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 출고일자는 &#39;년-월-일&#39;(<code>&#39;%Y-%m-%d&#39;</code>)만 보여주기 위해 <code>DATE_FORMAT(date, format)</code>함수를 사용하고, 출고여부는 5월 1일(<code>&#39;05-01&#39;</code>)을 기준으로 <code>출고미정</code>, <code>출고대기</code>, <code>출고완료</code>이 정해지므로 <code>CASE~END</code>절로 조건문을 작성한다. 또한 <code>ORDER BY</code>절을 사용하여 주문 ID(<code>ORDER_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h2 id="📌-level-4">📌 Level 4</h2>
<h3 id="🟩-취소되지-않은-진료-예약-조회하기">🟩 취소되지 않은 진료 예약 조회하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/132204">https://school.programmers.co.kr/learn/courses/30/lessons/132204</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT A.APNT_NO, B.PT_NAME, A.PT_NO, A.MCDP_CD, C.DR_NAME, A.APNT_YMD
  FROM (SELECT * FROM APPOINTMENT WHERE DATE_FORMAT(APNT_YMD, &#39;%Y-%m-%d&#39;) =&#39;2022-04-13&#39; AND MCDP_CD=&#39;CS&#39; AND APNT_CNCL_YN=&#39;N&#39;) A
  JOIN PATIENT B
  ON A.PT_NO=B.PT_NO
  JOIN DOCTOR C
  ON A.MDDR_ID=C.DR_ID
  ORDER BY APNT_YMD ASC, PT_NO ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>PATIENT</code> 테이블, <code>DOCTOR</code> 테이블, <code>APPOINMENT</code> 테이블에서 진료예약번호(<code>A.APNT_NO</code>), 환자이름(<code>B.PT_NAME</code>), 환자번호(<code>A.PT_NO</code>), 진료과코드(<code>A.MCDP_CD</code>), 의사이름(<code>C.DR_NAME</code>), 진료예약일시(<code>A.APNT_YMD</code>) 항목이 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다. 우선 2022년 4월 13일(<code>DATE_FORMAT(APNT_YMD, &#39;%Y-%m-%d&#39;) =&#39;2022-04-13&#39;</code>) 취소되지 않은(<code>APNT_CNCL_YN=&#39;N&#39;</code>) 흉부외과(CS) 진료(<code>MCDP_CD=&#39;CS&#39;</code>) 예약 내역을 조회하기 위해 <code>APPOINTMENT</code> 테이블에서 <code>SELECT~FROM</code>문을 사용하고, <code>WHERE 조건</code>절을 추가한다. 앞의 테이블 <code>A</code>라고 별칭을 붙이고, <code>A</code> 테이블과 <code>PATIENT</code> 테이블을 환자번호(<code>PT_NO</code>)로 내부 조인(<code>INNER JOIN</code>)한다. 또한 앞의 테이블과 <code>DOCTOR</code> 테이블을 의사ID(<code>A.MDDR_ID=C.DR_ID</code>)로 내부 조인(<code>INNER JOIN</code>)한다. 그 결과는 <code>ORDER BY</code>절을 사용하여 진료예약일시(<code>APNT_YMD</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬하고, 진료예약일시가 같다면 환자번호(<code>PT_NO</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL_프로그래머스-5]]></title>
            <link>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-5</link>
            <guid>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-5</guid>
            <pubDate>Fri, 21 Oct 2022 08:13:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚩 프로그래머스(programmers)에서 제공하는 SQL 문제풀기
🚩 JOIN</p>
</blockquote>
<h2 id="📌-level-2">📌 Level 2</h2>
<h3 id="🟩-상품-별-오프라인-매출-구하기">🟩 상품 별 오프라인 매출 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131533">https://school.programmers.co.kr/learn/courses/30/lessons/131533</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT PRODUCT_CODE, SUM(PRICE*SALES_AMOUNT) AS SALES
  FROM PRODUCT A
  JOIN OFFLINE_SALE B
  ON A.PRODUCT_ID=B.PRODUCT_ID
  GROUP BY PRODUCT_CODE
  ORDER BY SALES DESC, PRODUCT_CODE ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>PRODUCT</code> 테이블과 <code>OFFLINE_SALE</code> 테이블에서 상품코드(<code>PRODUCT_CODE</code>) 별 매출액(판매가<code>PRICE</code> * 판매량<code>SALES_AMOUNT</code>) 합계(<code>SALES</code>)를 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다. 상품코드(<code>PRODUCT_ID</code>)로 내부 조인(<code>INNER JOIN</code>)하고, 상품코드별 매출액의 합계를 구하기 위해 <code>GROUP BY</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 매출액(<code>SALES</code>)을 기준으로 내림차순(<code>DESC</code>) 정렬하고, 매출액이 같다면 상품코드(<code>PRODUCT_CODE</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<hr>
<h2 id="📌-level-3">📌 Level 3</h2>
<h3 id="🟩-오랜-기간-보호한-동물1">🟩 오랜 기간 보호한 동물(1)</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59044">https://school.programmers.co.kr/learn/courses/30/lessons/59044</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT I.NAME, I.DATETIME
  FROM ANIMAL_INS I
  LEFT OUTER JOIN ANIMAL_OUTS O
  ON I.ANIMAL_ID=O.ANIMAL_ID
  WHERE O.DATETIME IS NULL
  ORDER BY I.DATETIME ASC
  LIMIT 3;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블과 <code>ANIMAL_OUTS</code> 테이블에서 동물 이름(<code>NAME</code>)과 보호 시작일(<code>DATETIME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 동물의 아이디(<code>ANIMAL_ID</code>)로 외부 조인(<code>OUTER JOIN</code>)하고, 아직 입양을 못 간 동물(<code>O.DATETIME IS NULL</code>) 조건을 <code>WHERE 조건</code>절로 추가한다. 또한 가장 오래 보호소에 있었던 동물로 나열하기 위해 <code>ORDER BY</code>절을 사용하여 보호 시작일(<code>I.DATETIME</code>)로 오름차순(<code>ASC</code>) 정렬하고, <code>LIMIT 숫자</code>를 사용하여 동물 3마리만 조회한다.</p>
<h3 id="🟩-있었는데요-없었습니다">🟩 있었는데요 없었습니다</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59043">https://school.programmers.co.kr/learn/courses/30/lessons/59043</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT I.ANIMAL_ID, I.NAME
  FROM ANIMAL_INS I
  JOIN ANIMAL_OUTS O
  ON I.ANIMAL_ID=O.ANIMAL_ID
  WHERE I.DATETIME &gt; O.DATETIME
  ORDER BY I.DATETIME ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블과 <code>ANIMAL_OUTS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 동물의 아이디(<code>ANIMAL_ID</code>)로 내부 조인(<code>INNER JOIN</code>)하고, 보호 시작일보다 입양일이 더 빠른 동물(<code>I.DATETIME &gt; O.DATETIME</code>) 조건을 <code>WHERE 조건</code>절로 추가한다. 또한 <code>ORDER BY</code>절을 사용하여 보호 시작일(<code>I.DATETIME</code>)이 빠른 순로 조회하기 위해 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-없어진-기록-찾기">🟩 없어진 기록 찾기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59042">https://school.programmers.co.kr/learn/courses/30/lessons/59042</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT O.ANIMAL_ID, O.NAME
  FROM ANIMAL_INS I
  RIGHT OUTER JOIN ANIMAL_OUTS O
  ON I.ANIMAL_ID=O.ANIMAL_ID
  WHERE I.DATETIME IS NULL
  ORDER BY O.ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블과 <code>ANIMAL_OUTS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 동물의 아이디(<code>ANIMAL_ID</code>)로 외부 조인(<code>OUTER JOIN</code>)하고, 동물 보호소에 들어온 기록이 없는 동물(<code>I.DATETIME IS NULL</code>) 조건을 <code>WHERE 조건</code>절로 추가한다. 또한 <code>ORDER BY</code>절을 사용하여 동물의 아이디(<code>ANIMAL_ID</code>)순으로 조회하기 위해 오름차순(<code>ASC</code>) 정렬한다.</p>
<hr>
<h2 id="📌-level-4">📌 Level 4</h2>
<h3 id="🟩-보호소에서-중성화한-동물">🟩 보호소에서 중성화한 동물</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59045">https://school.programmers.co.kr/learn/courses/30/lessons/59045</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
  FROM ANIMAL_INS I
  JOIN ANIMAL_OUTS O
  ON I.ANIMAL_ID=O.ANIMAL_ID
  WHERE (SEX_UPON_INTAKE LIKE &#39;Intact%&#39;) AND (SEX_UPON_OUTCOME LIKE &#39;Spayed%&#39; OR SEX_UPON_OUTCOME LIKE &#39;Neutered%&#39;)
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블과 <code>ANIMAL_OUTS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 생물 종(<code>ANIMAL_TYPE</code>), 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 동물의 아이디(<code>ANIMAL_ID</code>)로 내부 조인(<code>INNER JOIN</code>)하고, 보호소에 들어올 당시에는 중성화되지 않았지만(<code>SEX_UPON_INTAKE LIKE &#39;Intact%&#39;</code>), 보호소를 나갈 당시에는 중성화된 동물(<code>SEX_UPON_OUTCOME LIKE &#39;Spayed%&#39; OR SEX_UPON_OUTCOME LIKE &#39;Neutered%&#39;</code>) 조건을 <code>WHERE 조건</code>절로 추가한다. 또한 <code>ORDER BY</code>절을 사용하여 동물의 아이디(<code>ANIMAL_ID</code>)순으로 조회하기 위해 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-5월-식품들의-총매출-조회하기">🟩 5월 식품들의 총매출 조회하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131117">https://school.programmers.co.kr/learn/courses/30/lessons/131117</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT A.PRODUCT_ID, A.PRODUCT_NAME, SUM(A.PRICE*B.AMOUNT) AS TOTAL_SALES
  FROM FOOD_PRODUCT A
  JOIN FOOD_ORDER B
  ON A.PRODUCT_ID=B.PRODUCT_ID
  WHERE DATE_FORMAT(PRODUCE_DATE, &#39;%Y-%m&#39;)=&#39;2022-05&#39;
  GROUP BY A.PRODUCT_ID
  ORDER BY TOTAL_SALES DESC, PRODUCT_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>FOOD_PRODUCT</code> 테이블과 <code>FOOD_ORDER</code> 테이블에서 식품 ID(<code>PRODUCT_ID</code>), 식품 이름(<code>PRODUCT_NAME</code>), 총매출(<code>TOTAL_SALES</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 식품 ID(<code>PRODUCT_ID</code>)로 내부 조인(<code>INNER JOIN</code>)하고, 생산일자가 2022년 5월인 식품(<code>DATE_FORMAT(PRODUCE_DATE, &#39;%Y-%m&#39;)=&#39;2022-05&#39;</code>) 조건을 <code>WHERE 조건</code>절로 추가한다. <code>GROUP BY</code>절로 식품 ID(<code>PRODUCT_ID</code>)로 묶어 총매출(<code>SUM(A.PRICE*B.AMOUNT)</code>)을 계산한다. 또한 <code>ORDER BY</code>절을 사용하여 총매출(<code>TOTAL_SALES</code>)을 기준으로 내림차순(<code>DESC</code>) 정렬하고, 총매출이 같다면 식품 ID(<code>PRODUCT_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-그룹별-조건에-맞는-식당-목록-출력하기">🟩 그룹별 조건에 맞는 식당 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131124">https://school.programmers.co.kr/learn/courses/30/lessons/131124</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT A.MEMBER_NAME, B.REVIEW_TEXT, DATE_FORMAT(B.REVIEW_DATE, &#39;%Y-%m-%d&#39;) AS REVIEW_DATE
  FROM MEMBER_PROFILE A
  JOIN REST_REVIEW B
  ON A.MEMBER_ID=B.MEMBER_ID
  WHERE B.MEMBER_ID IN (
  SELECT MEMBER_ID FROM REST_REVIEW GROUP BY MEMBER_ID HAVING COUNT(MEMBER_ID) = 
  (SELECT MAX(C.count) FROM (SELECT COUNT(MEMBER_ID) AS count FROM REST_REVIEW GROUP BY MEMBER_ID) C))
  ORDER BY REVIEW_DATE ASC, REVIEW_TEXT ASC;</code></pre>
<p><strong>3. 코드 해석</strong></p>
<hr>
<h2 id="📌-level-5">📌 Level 5</h2>
<h3 id="🟩-상품을-구매한-회원-비율-구하기">🟩 상품을 구매한 회원 비율 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131534">https://school.programmers.co.kr/learn/courses/30/lessons/131534</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT YEAR(A.SALES_DATE) AS YEAR, MONTH(A.SALES_DATE) AS MONTH, COUNT(DISTINCT(A.USER_ID)) AS PUCHASED_USERS, 
ROUND(COUNT(DISTINCT(A.USER_ID)) / (SELECT COUNT(*) FROM USER_INFO B WHERE YEAR(JOINED)=2021), 1) AS PUCHASED_RATIO
  FROM ONLINE_SALE A
  JOIN USER_INFO B
  ON A.USER_ID=B.USER_ID
  WHERE YEAR(B.JOINED)=2021
  GROUP BY YEAR, MONTH
  ORDER BY YEAR ASC, MONTH ASC;</code></pre>
<p><strong>3. 코드 해석</strong></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL_프로그래머스-4]]></title>
            <link>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4</link>
            <guid>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4</guid>
            <pubDate>Thu, 20 Oct 2022 17:16:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚩 프로그래머스(programmers)에서 제공하는 SQL 문제풀기
🚩 IS NULL</p>
</blockquote>
<h2 id="📌-level-1">📌 Level 1</h2>
<h3 id="🟩-이름이-있는-동물의-아이디">🟩 이름이 있는 동물의 아이디</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59407">https://school.programmers.co.kr/learn/courses/30/lessons/59407</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID
  FROM ANIMAL_INS
  WHERE NAME IS NOT NULL
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 ID(<code>ANIMAL_ID</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 동물 보호소에 들어온 동물 중에서 이름이 있는 동물(<code>NAME IS NULL</code>) 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 동물의 ID(<code>ANIMAL_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-이름이-없는-동물의-아이디">🟩 이름이 없는 동물의 아이디</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59039">https://school.programmers.co.kr/learn/courses/30/lessons/59039</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID
  FROM ANIMAL_INS
  WHERE NAME IS NULL
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 ID(<code>ANIMAL_ID</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 동물 보호소에 들어온 동물 중에서 이름이 없는 채로 들어온 동물(<code>NAME IS NULL</code>) 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 동물의 ID(<code>ANIMAL_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-경기도에-위치한-식품창고-목록-출력하기">🟩 경기도에 위치한 식품창고 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131114">https://school.programmers.co.kr/learn/courses/30/lessons/131114</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT WAREHOUSE_ID, WAREHOUSE_NAME, ADDRESS, IFNULL(FREEZER_YN, &#39;N&#39;)
  FROM FOOD_WAREHOUSE
  WHERE ADDRESS LIKE &#39;경기도%&#39;
  ORDER BY WAREHOUSE_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>FOOD_WAREHOUSE</code> 테이블에서 창고의 ID(<code>WAREHOUSE_ID</code>), 이름(<code>WAREHOUSE_NAME</code>), 주소(<code>ADDRESS</code>), 냉동시설 여부(<code>FREEZER_YN</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 냉동시설 여부(<code>FREEZER_YN</code>)가 NULL인 경우, &#39;N&#39;으로 출력하기 위해 <code>IFNULL(열이름,대체값)</code>함수를 사용한다. 이때 경기도에 위치한 창고(<code>ADDRESS LIKE &#39;경기도%&#39;</code>) 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 창고 ID(<code>WAREHOUSE_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-나이-정보가-없는-회원-수-구하기">🟩 나이 정보가 없는 회원 수 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131528">https://school.programmers.co.kr/learn/courses/30/lessons/131528</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT COUNT(*) AS USERS
  FROM USER_INFO
  WHERE AGE IS NULL;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>USER_INFO</code> 테이블에서 나이 정보가 없는 회원이 몇 명인지 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 나이 정보가 없다(<code>AGE IS NULL</code>)라는 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용하고, <code>COUNT(*)</code>함수로 회원이 몇 명인지 계산하고 컬럼명 별칭은 <code>USERS</code>로 지정한다.</p>
<hr>
<h2 id="📌-level-2">📌 Level 2</h2>
<h3 id="🟩-null-처리하기">🟩 NULL 처리하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59410">https://school.programmers.co.kr/learn/courses/30/lessons/59410</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_TYPE, IFNULL(NAME, &quot;No name&quot;), SEX_UPON_INTAKE
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 생물 종(<code>ANIMAL_TYPE</code>), 이름(<code>NAME</code>), 성별 및 중성화 여부(<code>SEX_UPON_INTAKE</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 이름이 없는 동물의 이름(<code>NAME</code>)은 &quot;No name&quot;으로 표시하기 위해 <code>IFNULL(열이름,대체값)</code>함수를 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 동물의 아이디(<code>ANIMAL_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL_프로그래머스-3]]></title>
            <link>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3</link>
            <guid>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3</guid>
            <pubDate>Tue, 18 Oct 2022 03:29:56 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚩 프로그래머스(programmers)에서 제공하는 SQL 문제풀기
🚩 GROUP BY</p>
</blockquote>
<h2 id="📌-level-2">📌 Level 2</h2>
<h3 id="🟩-동명-동물-수-찾기">🟩 동명 동물 수 찾기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59041">https://school.programmers.co.kr/learn/courses/30/lessons/59041</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT NAME, COUNT(*) AS COUNT
  FROM ANIMAL_INS
  GROUP BY NAME
  HAVING COUNT &gt;= 2 AND NAME IS NOT NULL
  ORDER BY NAME ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물 이름 중 두 번 이상 쓰인 이름(<code>NAME</code>)과 해당 이름이 쓰인 횟수(<code>COUNT</code>)을 조회하기 위해 <code>SELECT~FROM문</code>을 사용한다. 이때 <code>GROUP BY</code>절을 활용하여 동물 이름(<code>NAME</code>)으로 그룹화하고, <code>HAVING 조건</code>절로 각 그룹에서 두 번 이상 쓰인 횟수(<code>COUNT &gt;= 2</code>)이면서 이름이 없는 동물은 집계에서 제외(<code>NAME IS NOT NULL</code>)하는 조건을 추가한다. 또한 이름(<code>NAME</code>)순으로 나열해야 되므로 <code>ORDER BY</code>절과 오름차순 정렬인 <code>ASC</code>를 추가한다.</p>
<h3 id="🟩-고양이와-개는-몇-마리-있을까">🟩 고양이와 개는 몇 마리 있을까</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59040">https://school.programmers.co.kr/learn/courses/30/lessons/59040</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_TYPE, COUNT(*) AS count
  FROM ANIMAL_INS
  GROUP BY ANIMAL_TYPE
  ORDER BY ANIMAL_TYPE ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물 중 고양이와 개가 각각 몇 마리인지를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 고양이와 개는 생물 종(<code>ANIMAL_TYPE</code>)으로 파악이 가능하기 때문에 <code>GROUP BY</code>절을 활용하여 생물 종(<code>ANIMAL_TYPE</code>)으로 그룹화하고, 이때 각각 몇 마리인지는 <code>COUNT(*)</code>함수로 알 수 있다. 고양이를 개보다 먼저 조회하기 위해 생물 종(<code>ANIMAL_TYPE</code>)순으로 나열해야 되므로 <code>ORDER BY</code>절과 오름차순 정렬인 <code>ASC</code>를 추가한다.</p>
<h3 id="🟩-입양-시각-구하기1">🟩 입양 시각 구하기(1)</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59412">https://school.programmers.co.kr/learn/courses/30/lessons/59412</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT DATE_FORMAT(DATETIME, &#39;%k&#39;) AS HOUR, COUNT(*) AS COUNT
  FROM ANIMAL_OUTS
  GROUP BY HOUR
  HAVING HOUR &gt;= 9 AND HOUR &lt;= 19
  ORDER BY HOUR*1 ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_OUTS</code> 테이블에서 몇 시에 입양이 가장 활발하게 일어났는지 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 입양일(<code>DATETIME</code>)에서 입양 시간 중에 시간대(<code>%k</code>)만 추출하기 위해 <code>DATE_FORMAT(날짜,형식)</code>함수를 사용하고 별칭을 <code>HOUR</code>로 한다. <code>GROUP BY</code>절을 활용하여 시간대(<code>HOUR</code>)로 그룹화하고, <code>HAVING 조건</code>절로 09:00부터 19:59까지(<code>HOUR &gt;= 9 AND HOUR &lt;= 19</code>)의 조건을 추가한다. 따라서 각 시간대별로 입양이 몇 건이나 발생했는지는 <code>COUNT(*)</code>함수로 알 수 있다. 또한 시간대(<code>HOUR</code>)순으로 나열해야 되므로 <code>ORDER BY</code>절과 오름차순 정렬인 <code>ASC</code>를 추가한다.</p>
<h3 id="🟩-가격대-별-상품-개수-구하기">🟩 가격대 별 상품 개수 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131530">https://school.programmers.co.kr/learn/courses/30/lessons/131530</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT TRUNCATE(PRICE, -4) AS PRICE_GROUP, COUNT(*) AS PRODUCTS
  FROM PRODUCT
  GROUP BY PRICE_GROUP
  ORDER BY PRICE_GROUP ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>PRODUCT</code> 테이블에서 만원 단위의 가격대 별로 상품 개수를 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 판매가(<code>PRICE</code>)는 <code>TRUNCATE(숫자, 버림할 자릿수)</code>함수를 사용하여 0원 ~ 1만원 미만은 0, 1만원 이상 ~ 2만원 미만은 1, ..., 으로 가격대를 만들고 해당 별칭을 <code>PRICE_GROUP</code>으로 한다. <code>GROUP BY</code>절을 활용하여 가격대(<code>PRICE_GROUP</code>)로 그룹화하고, 이때 가격대 별 상품 개수가 몇 개인지는 <code>COUNT(*)</code>함수로 알 수 있다. 가격대(<code>PRICE_GROUP</code>)를 기준으로 나열해야 되므로 <code>ORDER BY</code>절과 오름차순 정렬인 <code>ASC</code>를 추가한다.</p>
<h3 id="🟩-진료과별-총-예약-횟수-출력하기">🟩 진료과별 총 예약 횟수 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/132202">https://school.programmers.co.kr/learn/courses/30/lessons/132202</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT MCDP_CD AS 진료과코드, COUNT(*) AS 5월예약건수
  FROM APPOINTMENT
  WHERE MONTH(APNT_YMD)=5
  GROUP BY 진료과코드
  ORDER BY 5월예약건수 ASC, 진료과코드 ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>APPOINMENT</code> 테이블에서 2022년 5월에 예약한 환자 수를 진료과코드 별로 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. <code>WHERE</code>절에 2022년 5월 예약(<code>MONTH(APNT_YMD)=5</code>)의 조건을 추가한다. <code>GROUP BY</code>절을 활용하여 진료과코드(<code>MCDP_CD</code>)로 그룹화하한다. 따라서 각 진료과별 예약한 환자 수가 몇 명인지는 <code>COUNT(*)</code>함수로 알 수 있다. 또한 <code>ORDER BY</code>절을 사용하여 진료과별 예약한 환자 수(<code>5월예약건수</code>)기준으로 오름차순 정렬(<code>ASC</code>)하고,  예약한 환자 수가 같다면 진료과 코드(<code>진료과코드</code>)를 기준으로 오름차순 정렬(<code>ASC</code>)한다.</p>
<hr>
<h2 id="📌-level-3">📌 Level 3</h2>
<h3 id="🟩-즐겨찾기가-가장-많은-식당-정보-출력하기">🟩 즐겨찾기가 가장 많은 식당 정보 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131123">https://school.programmers.co.kr/learn/courses/30/lessons/131123</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT A.FOOD_TYPE, A.REST_ID, A.REST_NAME, A.FAVORITES
  FROM (SELECT FOOD_TYPE, MAX(FAVORITES) AS MAX_FAVORITES FROM REST_INFO GROUP BY FOOD_TYPE) B
  JOIN REST_INFO A
  ON A.FOOD_TYPE = B.FOOD_TYPE
  WHERE A.FAVORITES = B.MAX_FAVORITES
  ORDER BY A.FOOD_TYPE DESC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>REST_INFO</code> 테이블에서 음식종류별로 즐겨찾기수가 가장 많은 식당의 음식 종류(<code>FOOD_TYPE</code>), ID(<code>REST_ID</code>), 식당 이름(<code>REST_NAME</code>), 즐겨찾기수(<code>FAVORITES</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 <code>GROUP BY</code>절을 활용하여 음식종류(<code>FOOD_TYPE</code>)로 그룹화하고, <code>MAX()함수</code>를 사용하여 음식종류별 즐겨찾기수(<code>FAVORITES</code>)가 가장 많은 음식종류(<code>FOOD_TYPE</code>)와 즐겨찾기수(<code>FAVORITES</code>)를 조회하는 <code>SELECT~FROM</code>문을 만든다(<code>B</code>테이블). <code>B</code>테이블과 <code>REST_INFO</code>테이블을 내부 조인(<code>INNER JOIN</code>)을 활용하여 즐겨찾기수(<code>FAVORITES</code>)로 묶어서 <code>WHERE 조건</code>으로 음식종류별로 즐겨찾기수가 가장 많은 식당을 조회한다. 음식 종류(<code>FOOD_TYPE</code>)를 기준으로 나열해야 되므로 <code>ORDER BY</code>절과 내림차순 정렬인 <code>DESC</code>를 추가한다.</p>
<hr>
<h2 id="📌-level-4">📌 Level 4</h2>
<h3 id="🟩-입양-시각-구하기2">🟩 입양 시각 구하기(2)</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59413">https://school.programmers.co.kr/learn/courses/30/lessons/59413</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">WITH RECURSIVE HOUR_TABLE AS(
    SELECT 0 AS HOUR
    UNION ALL
    SELECT HOUR+1 FROM HOUR_TABLE WHERE HOUR &lt; 23
)
SELECT HOUR_TABLE.HOUR, COUNT(ANIMAL_ID) AS COUNT
FROM HOUR_TABLE
LEFT OUTER JOIN ANIMAL_OUTS
ON HOUR(DATETIME) = HOUR_TABLE.HOUR
GROUP BY HOUR_TABLE.HOUR
ORDER BY HOUR_TABLE.HOUR;</code></pre>
<p><strong>3. 코드 해석</strong></p>
<h3 id="🟩-식품분류별-가장-비싼-식품의-정보-조회하기">🟩 식품분류별 가장 비싼 식품의 정보 조회하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131116">https://school.programmers.co.kr/learn/courses/30/lessons/131116</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
  FROM FOOD_PRODUCT
  WHERE CATEGORY IN (&#39;과자&#39;, &#39;국&#39;, &#39;김치&#39;, &#39;식용유&#39;) AND PRICE IN (SELECT MAX(PRICE) FROM FOOD_PRODUCT GROUP BY CATEGORY) 
  ORDER BY MAX_PRICE DESC;</code></pre>
<p><strong>3. 코드 해석</strong></p>
<h3 id="🟩-년-월-성별-별-상품-구매-회원-수-구하기">🟩 년, 월, 성별 별 상품 구매 회원 수 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131532">https://school.programmers.co.kr/learn/courses/30/lessons/131532</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT YEAR(SALES_DATE) AS YEAR, MONTH(SALES_DATE) AS MONTH, GENDER, COUNT(DISTINCT(A.USER_ID)) AS USERS
  FROM USER_INFO A
  JOIN ONLINE_SALE B
  ON A.USER_ID = B.USER_ID
  WHERE GENDER IS NOT NULL
  GROUP BY YEAR, MONTH, GENDER
  ORDER BY YEAR ASC, MONTH ASC, GENDER ASC;</code></pre>
<p><strong>3. 코드 해석</strong></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL_프로그래머스-2]]></title>
            <link>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2</link>
            <guid>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2</guid>
            <pubDate>Sun, 16 Oct 2022 17:24:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚩 프로그래머스(programmers)에서 제공하는 SQL 문제풀기
🚩 SUM, MAX, MIN</p>
</blockquote>
<h2 id="📌-level-1">📌 Level 1</h2>
<h3 id="🟩-최댓값-구하기">🟩 최댓값 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59415">https://school.programmers.co.kr/learn/courses/30/lessons/59415</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT MAX(DATETIME) AS 시간
  FROM ANIMAL_INS;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 가장 최근에 들어온 동물의 시간(<code>MAX(DATETIME) AS 시간</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다.</p>
<h3 id="🟩-가장-비싼-상품-구하기">🟩 가장 비싼 상품 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131697">https://school.programmers.co.kr/learn/courses/30/lessons/131697</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT MAX(PRICE) AS MAX_PRICE
  FROM PRODUCT;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>PRODUCT</code> 테이블에서 가장 높은 판매가(<code>MAX(PRICE) AS MAX_PRICE</code>)를 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다.</p>
<hr>
<h2 id="📌-level-2">📌 Level 2</h2>
<h3 id="🟩-중복-제거하기">🟩 중복 제거하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59408">https://school.programmers.co.kr/learn/courses/30/lessons/59408</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT COUNT(DISTINCT(NAME)) AS count
  FROM ANIMAL_INS
  WHERE NAME != &#39;NULL&#39;;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 중복되는 이름은 하나로 하여 동물 보호소에 들어온 동물의 이름은 몇 개인지(<code>COUNT(DISTINCT(NAME)) AS count</code>) 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 이름이 NULL인 경우를 제외(<code>NAME != &#39;NULL&#39;</code>)하기 위해 <code>WHERE조건</code>절을 사용한다.</p>
<h3 id="🟩-동물-수-구하기">🟩 동물 수 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59406">https://school.programmers.co.kr/learn/courses/30/lessons/59406</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT COUNT(ANIMAL_ID) AS count
  FROM ANIMAL_INS;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물 보호소에 동물이 몇 마리 들어왔는지(<code>COUNT(ANIMAL_ID) AS count</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다.</p>
<h3 id="🟩-최솟값-구하기">🟩 최솟값 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59038">https://school.programmers.co.kr/learn/courses/30/lessons/59038</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT MIN(DATETIME) AS 시간
  FROM ANIMAL_INS;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물 보호소에 가장 먼저 들어온 동물의 시간(<code>MIN(DATETIME) AS 시간</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다.</p>
<h3 id="🟩-가격이-제일-비싼-식품의-정보-출력하기">🟩 가격이 제일 비싼 식품의 정보 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131115">https://school.programmers.co.kr/learn/courses/30/lessons/131115</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT *
  FROM FOOD_PRODUCT
  ORDER BY PRICE DESC
  LIMIT 1;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>FOOD_PRODUCT</code> 테이블에서 모든 컬럼명(<code>*</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 가격이 제일 비싼 식품을 찾기 위해 <code>ORDER BY</code>절로 가격(<code>PRICE</code>)의 내림차순(<code>DESC</code>)으로 정렬하고 <code>LIMIT 1</code>로 맨 처음 하나의 행만을 조회한다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-7]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-7</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-7</guid>
            <pubDate>Thu, 13 Oct 2022 08:50:35 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-8강-sql과-파이썬python-연결">📌 8강 SQL과 파이썬(Python) 연결</h2>
<h3 id="✔️-08-1-파이썬-개발-환경">✔️ 08-1 파이썬 개발 환경</h3>
<ul>
<li><p><strong>파이썬(Python)</strong></p>
<ul>
<li>장점<ul>
<li>무료로 강력한 기능을 사용할 수 있음</li>
<li>설치와 사용 환경 구축이 쉬움</li>
<li>다양하고 강력한 외부 라이브러리들이 많음</li>
</ul>
</li>
<li><code>PyMySQL</code> 외부 라이브러리 설치: 파이썬을 MySQL과 연결해주는 대표적인 외부 라이브러리</li>
</ul>
</li>
<li><p><strong>파이썬 설치</strong></p>
<ul>
<li><span style='color:red'>1) 파이썬 다운로드</span>: <a href="https://www.python.org/">https://www.python.org/</a> 에서 <code>Downloads</code> 클릭 후 <code>Download Python 3.x.x</code> 버튼 클릭</li>
<li><span style='color:red'>2) 파이썬 설치하기</span>: 다운로드한 <code>python-3.x.x-amd64.exe</code> 파일을 더블 클릭하고 설치<ul>
<li>설치시 <code>Add Python 3.x to PATH</code> 체크 후 <code>Install Now</code> 버튼 클릭</li>
<li>설치 후 <code>Close</code> 버튼 클릭</li>
</ul>
</li>
<li><span style='color:red'>3) 외부 라이브러리 설치하기</span><ul>
<li><code>cmd</code> 창에서 <code>pip install pymysql</code> 입력</li>
<li>설치 후 성공 메시지 <code>Successfully installed pymysql-x.x.x</code> 확인</li>
<li><code>cmd</code> 창에서 <code>exit</code> 입력</li>
</ul>
</li>
<li><span style='color:red'>4) 파이썬 사용법</span><ul>
<li>Python의 <code>IDLE</code> 환경(한 줄 실행, 여러 줄 실행)<ul>
<li>윈도우의 <code>시작</code> 버튼 클릭 후 <code>Python 3.x</code> 파일에 <code>IDLE</code> 클릭</li>
</ul>
</li>
<li>한 줄 실행(<strong>대화형 모드</strong>)<ul>
<li>한 줄 실행: 한 줄 입력하고 <code>Enter</code> 키를 누르면 바로 실행</li>
<li>프로그램 종료: <code>File</code>-<code>Exit</code> 메뉴 클릭</li>
</ul>
</li>
<li>여러 줄 실행(<strong>스크립트 모드</strong>)<ul>
<li><code>File</code>-<code>New File</code> 메뉴 클릭 후 새 창에서 코딩</li>
<li><code>File</code>-<code>Save</code> 메뉴 클릭 후 파일 이름 지정 후 저장</li>
<li>여러 줄 실행: 파일이름.py창에서 <code>Run</code>-<code>Run Module</code> 메뉴 선택 또는 <code>F5</code>키 누르기</li>
<li>프로그램 종료: <code>File</code>-<code>Exit</code> 메뉴 클릭<h3 id="✔️-08-2-파이썬과-mysql의-연동">✔️ 08-2 파이썬과 MySQL의 연동</h3>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>연동 프로그래밍: MySQL에서 데이터 입력</strong></p>
<ul>
<li><span style='color:red'>1) MySQL 워크벤치 실행 후 데이터베이스 구축</span><pre><code class="language-sql">DROP DATABASE IF EXISTS 데이터베이스_이름;
CREATE DATABASE 데이터베이스_이름;</code></pre>
</li>
<li><span style='color:red'>2) MySQL의 데이터 입력을 위한 파이썬 코딩</span>
<strong>1. MySQL 연결하기</strong>: <code>연결자=pymysql.connect(연결 옵션)</code><ul>
<li>MySQL를 사용하기 위해 import pymysql 후 pymysql.connect()로 <span style='color:blue'>데이터베이스와 연동</span></li>
<li>conn 변수는 데이터베이스와 연결된 <span style='color:blue'>연결자</span><pre><code class="language-python">import pymysql
conn = pymysql.connect(host=서버IP주소, user=사용자, password=암호, db=데이터베이스, charset=문자세트)</code></pre>
</li>
<li><em>2. 커서 생성하기*</em>: <code>커서이름=연결자.cursor()</code></li>
<li>커서는 데이터베이스에 SQL 문을 실행하거나 실행된 결과를 돌려받는 통로<pre><code class="language-python">cur = conn.cursor()</code></pre>
</li>
<li><em>3. 테이블 만들기*</em>: <code>커서이름.execute(&quot;CREATE TABLE 문장&quot;)</code></li>
<li>테이블을 만드는 SQL 문을 <code>커서이름.execute()</code> 함수의 매개변수로 넘겨주면 SQL 문이 데이터베이스에 실행됨<pre><code class="language-python">cur.execute(&quot;CREATE TABLE 테이블_이름 (열_이름1 데이터형식, 열_이름2 데이터형식, ...)&quot;)</code></pre>
</li>
<li><em>4. 데이터 입력하기(반복)*</em>: <code>커서이름.execute(&quot;INSERT 문장&quot;)</code></li>
<li>데이터 입력도 SQL 문을 사용해야 하므로 <code>커서이름.execute()</code> 함수를 사용함<pre><code class="language-python">cur.execute(&quot;INSERT INTO 테이블_이름 VALUES(데이터1, 데이터2, ...)&quot;)
cur.execute(&quot;INSERT INTO 테이블_이름 VALUES(데이터1, 데이터2, ...)&quot;)</code></pre>
</li>
<li><em>5. 입력한 데이터 저장하기*</em>: <code>연결자.commit()</code></li>
<li><span style='color:blue'>커밋</span>: 앞에 입력한 데이터는 임시로 저장된 상태이므로 이를 확실하게 저장하기<pre><code class="language-python">conn.commit()</code></pre>
</li>
<li><em>6. MySQL 연결 종료하기*</em>: <code>연결자.close()</code></li>
<li>데이터베이스를 모두 사용했다면 연결한 데이터베이스를 닫아야 함<pre><code class="language-python">conn.close()</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>연동 프로그래밍: MySQL에서 데이터 조회</strong></p>
<ul>
<li><span style='color:red'>2) MySQL의 데이터 조회를 위한 파이썬 코딩</span>
<strong>1. MySQL 연결하기</strong>: <code>연결자=pymysql.connect(연결 옵션)</code><pre><code class="language-python">import pymysql
conn = pymysql.connect(host=서버IP주소, user=사용자, password=암호, db=데이터베이스, charset=문자세트)</code></pre>
<strong>2. 커서 생성하기</strong>: <code>커서이름=연결자.cursor()</code><pre><code class="language-python">cur = conn.cursor()</code></pre>
<strong>3. 데이터 조회하기</strong>: <code>커서이름.execute(&quot;SELECT 문장&quot;)</code><pre><code class="language-python">cur.execute(&quot;SELECT 열_이름 FROM 테이블_이름&quot;)</code></pre>
<strong>4. 조회한 데이터 출력하기(반복)</strong>: <code>커서이름.fetchone()</code><ul>
<li><code>fetchone()</code>: 한 행씩 접근하기</li>
<li><code>fetchall()</code>: 모든 행에 한꺼번에 접근하기<pre><code class="language-python">while (True):
row = cur.fetchone() -- 한 행씩 접근하기
if row == None:
  break
data1 = row[0]
data2 = row[1]
print(f&quot;{data1} {data2}&quot;)</code></pre>
</li>
<li><em>5. MySQL 연결 종료하기*</em>: <code>연결자.close()</code><pre><code class="language-python">conn.close()</code></pre>
<h3 id="✔️-08-3-gui-응용-프로그램">✔️ 08-3 GUI 응용 프로그램</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><p>파이썬을 통해 윈도에 출력되는 GUI 응용 프로그램 작성하기</p>
<ul>
<li><p><strong>GUI</strong>: Graphical User Interface의 약자, 윈도에 그래픽 환경으로 제공되는 화면</p>
</li>
<li><p><strong>tkinter</strong> 라이브러리: GUI 관련 모듈을 제공해주는 표준 윈도 라이브러리</p>
<ul>
<li>엑셀, 한글, 크롬 등의 응용 프로그램과 비슷한 형태의 프로그램을 만들 수 있음<pre><code class="language-python">from tkinter import *
root = Tk() -- 부모윈도
</code></pre>
</li>
</ul>
<h1 id="앞으로-이-부분에서-코딩을-추가해서-화면을-구성하고-처리함제목-크기-위젯-라벨버튼-등">앞으로 이 부분에서 코딩을 추가해서 화면을 구성하고 처리함(제목, 크기, 위젯-라벨,버튼 등)</h1>
<p>root.mainloop()
```</p>
</li>
<li><p><strong>제목 및 크기</strong></p>
<ul>
<li><code>root.title()</code>: 윈도 제목 지정</li>
<li><code>root.geometry(&quot;가로X세로&quot;)</code>: 윈도 크기 설정 <pre><code class="language-python">root.title(&quot;GUI 연습장&quot;)
root.geometry(&quot;400X200&quot;) -- root.geometry(&quot;가로X세로&quot;)</code></pre>
</li>
</ul>
</li>
<li><p><strong>위젯</strong>: 윈도에 나오는 버튼, 텍스트, 라디오 버튼, 이미지 등을 통합해서 지칭하는 용어</p>
<ul>
<li><code>pack()</code> 함수: 위젯을 화면에 나타나게 하는 함수</li>
<li><span style='color:red'>위젯의 정렬</span><ul>
<li><code>pack()</code> 함수의 옵션: 가로로 정렬하는 방법은 <code>side=LEFT</code> 또는 <code>side=RIGHT</code>, 수직으로 정렬하는 방법은 <code>side=TOP</code> 또는 <code>side=BOTTOM</code> 방식<pre><code class="language-python">button = Button(root, text=&quot;텍스트&quot;)
button.pack(side=LEFT) -- side=LEFT</code></pre>
</li>
</ul>
</li>
<li><span style='color:red'>위젯 사이 여백 추가</span><ul>
<li><code>pack()</code> 함수의 옵션: 여백을 주려면 <code>padx=픽셀값</code> 또는 <code>pady=픽셀값</code><pre><code class="language-python">button = Button(root, text=&quot;텍스트&quot;)
button.pack(side=TOP, fill=X, padx=10, pady=10) -- padx=픽셀값, pady=픽셀값</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>라벨</strong></p>
<ul>
<li><code>label(부모윈도, 옵션...)</code> 형식: 라벨(문자를 표현할 수 있는 위젯)<pre><code class="language-python">label = Label(root, text=&quot;텍스트입력&quot;)
label.pack()</code></pre>
</li>
</ul>
</li>
<li><p><strong>버튼</strong></p>
<ul>
<li><code>Button(부모윈도, 옵션...)</code> 형식: 라벨(마우스를 클릭하면 지정한 작업이 실행되도록 사용되는 위젯)<ul>
<li><code>command 옵션</code>: 사용자가 버튼을 눌렀을 때 지정한 작업을 처리해야 함<pre><code class="language-python">from tkinter import messagebox
</code></pre>
</li>
</ul>
</li>
</ul>
<p>def clickButton():
  messagebox.showinfo(&#39;제목&#39;, &#39;내용&#39;)</p>
<p>button = Button(root, text=&quot;클릭&quot;, fg=&quot;red&quot;, bg=&quot;yellow&quot;, command=clickButton)
button.pack(expand = 1)
```</p>
</li>
<li><p><strong>프레임</strong></p>
<ul>
<li>프레임: 화면을 여러 구역으로 나눌 때 사용함, <code>Frame(부모윈도)</code><pre><code class="language-python">upFrame = Frame(root)
upFrame.pack()
downFrame = Frame(root)
upFrame.pack()</code></pre>
</li>
</ul>
</li>
<li><p><strong>엔트리</strong></p>
<ul>
<li>엔트리: 입력 상자를 표현함, <code>Entry(윈도, 옵션...)</code><pre><code class="language-python">editBox = Entry(upFrame, width = 10)
editBox.pack(padx = 20, pady = 20)</code></pre>
</li>
</ul>
</li>
<li><p><strong>리스트 박스</strong></p>
<ul>
<li>리스트 박스: 목록을 표현함, <code>Listbox(윈도, 옵션...)</code><pre><code class="language-python">listbox = Listbox(downFrame, bg = &#39;yellow&#39;)
listbox.pack()
</code></pre>
</li>
</ul>
<p>listbox.insert(END, &#39;하나&#39;)</p>
<pre><code></code></pre></li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고문헌">📌 참고문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p372-p406.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL_프로그래머스-1]]></title>
            <link>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-1</link>
            <guid>https://velog.io/@so-kr/MySQL%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-1</guid>
            <pubDate>Wed, 12 Oct 2022 09:36:08 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚩 프로그래머스(programmers)에서 제공하는 SQL 문제풀기
🚩 SELECT</p>
</blockquote>
<h2 id="📌-level-1">📌 Level 1</h2>
<h3 id="🟩-동물의-아이디와-이름">🟩 동물의 아이디와 이름</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59403">https://school.programmers.co.kr/learn/courses/30/lessons/59403</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID ASC; -- 또는 ORDER BY ANIMAL_ID</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 이때 동물의 아이디(<code>ANIMAL_ID</code>)순으로 나열해야 되므로 <code>ORDER BY</code>절을 추가하여 정렬한다. <code>ORDER BY</code>절에서 데이터를 오름차순으로 정렬하는 <code>ASC</code>와 내림차순으로 정렬하는 <code>DESC</code>가 있으며 <code>ORDER BY</code> 정렬의 기본값(<code>Default</code>)은 <code>ASC</code>이기 때문에 현재 문제에서 <code>ASC</code>를 생략하고 코드를 작성해도 된다.</p>
<h3 id="🟩-여러-기준으로-정렬하기">🟩 여러 기준으로 정렬하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59404">https://school.programmers.co.kr/learn/courses/30/lessons/59404</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME, DATETIME
  FROM ANIMAL_INS
  ORDER BY NAME ASC, DATETIME DESC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>), 보호 시작일(<code>DATETIME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 또한 이때 이름(<code>NAME</code>)순으로 나열하면서 동시에 이름이 같은 동물 중에서 보호 시작일(<code>DATETIME</code>)이 나중인 동물을 먼저 보여줘야 하므로 <code>ORDER BY</code>절에 <code>NAME ASC</code>(오름차순)와 <code>DATETIME DESC</code>(내림차순)를 추가하여 정렬한다.</p>
<h3 id="🟩-아픈-동물-찾기">🟩 아픈 동물 찾기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59036">https://school.programmers.co.kr/learn/courses/30/lessons/59036</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
  WHERE INTAKE_CONDITION = &#39;Sick&#39;
  ORDER BY ANIMAL_ID;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 또한 동물 중에 아픈 동물만(<code>INTAKE_CONDITION = &#39;Sick&#39;</code>)을 조회하기 위해 <code>WHERE 조건</code>절을 사용한다. 추가적으로 <code>ORDER BY</code>절을 추가하여 아이디(<code>ANIMAL_ID</code>) 순으로 조회해야 한다.</p>
<h3 id="🟩-상위-n개-레코드">🟩 상위 n개 레코드</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59405">https://school.programmers.co.kr/learn/courses/30/lessons/59405</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT NAME
  FROM ANIMAL_INS
  ORDER BY DATETIME ASC
  LIMIT 1;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, <code>ORDER BY</code>절을 사용하여 보호 시작일(<code>DATETIME</code>)순으로 오름차순 정렬하고 이때 가장 먼저 들어온 동물 하나를 출력하기 <code>LIMIT 1</code>을 추가한다. <code>LIMIT</code>는 출력하는 개수를 제한하여 조회할 수 있다.</p>
<h3 id="🟩-어린-동물-찾기">🟩 어린 동물 찾기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59037">https://school.programmers.co.kr/learn/courses/30/lessons/59037</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT ANIMAL_ID, NAME
  FROM ANIMAL_INS
  WHERE INTAKE_CONDITION != &#39;Aged&#39;
  ORDER BY ANIMAL_ID;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 아이디(<code>ANIMAL_ID</code>)와 이름(<code>NAME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 또한 동물 중에 젊은 동물만(<code>INTAKE_CONDITION != &#39;Aged&#39;</code>)을 조회하기 위해 <code>WHERE 조건</code>절을 사용한다. 추가적으로 <code>ORDER BY</code>절을 추가하여 아이디(<code>ANIMAL_ID</code>) 순으로 조회해야 한다.</p>
<h3 id="🟩-역순-정렬하기">🟩 역순 정렬하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59035">https://school.programmers.co.kr/learn/courses/30/lessons/59035</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT NAME, DATETIME
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID DESC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 동물의 이름(<code>NAME</code>)과 보호 시작일(<code>DATETIME</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 동물의 아이디(<code>ANIMAL_ID</code>)역순으로 나열해야 되므로 <code>ORDER BY</code>절과 내림차순의 의미인 <code>DESC</code>을 추가하여 정렬한 결과를 조회한다.</p>
<h3 id="🟩-강원도에-위치한-생산공장-목록-출력하기">🟩 강원도에 위치한 생산공장 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131112">https://school.programmers.co.kr/learn/courses/30/lessons/131112</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
  FROM FOOD_FACTORY
  WHERE ADDRESS LIKE &#39;강원도%&#39;
  ORDER BY FACTORY_ID ASC; -- 또는 ORDER BY FACTORY_ID</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>FOOD_FACTORY</code> 테이블에서 강원도에 위치한 식품공장의 공장 ID(<code>FACTORY_ID</code>), 공장 이름(<code>FACTORY_NAME</code>), 주소(<code>ADDRESS</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 또한 강원도에 위치한 식품공장만(<code>ADDRESS LIKE &#39;강원도%&#39;</code>)을 조회하기 위해 <code>WHERE 조건</code>절을 사용한다. 이때 동물의 아이디(<code>FACTORY_ID</code>)를 기준으로 오름차순 정렬을 해야 되므로 <code>ORDER BY</code>절을 사용하고 오름차순의 의미인 <code>ASC</code>는 생략해도 된다.</p>
<h3 id="🟩-모든-레코드-조회하기">🟩 모든 레코드 조회하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/59034">https://school.programmers.co.kr/learn/courses/30/lessons/59034</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT *
  FROM ANIMAL_INS
  ORDER BY ANIMAL_ID ASC; -- 또는 ORDER BY ANIMAL_ID</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ANIMAL_INS</code> 테이블에서 모든 동물의 정보(<code>*</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 동물의 아이디(<code>ANIMAL_ID</code>)순으로 나열해야 되므로 <code>ORDER BY</code>절을 사용하여 정렬하고 오름차순의 의미인 <code>ASC</code>는 생략해도 된다.</p>
<h3 id="🟩-조건에-맞는-회원수-구하기">🟩 조건에 맞는 회원수 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131535">https://school.programmers.co.kr/learn/courses/30/lessons/131535</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT COUNT(USER_ID) AS USERS
  FROM USER_INFO
  WHERE (YEAR(JOINED)=&#39;2021&#39;) AND (AGE&gt;=20 AND AGE&lt;=29);</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>USER_INFO</code> 테이블에서 회원의 수(<code>COUNT(USER_ID)</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 2021년에 가입한 회원(<code>YEAR(JOINED)=&#39;2021&#39;</code>)중에서 나이가 20세 이상 29세 이하인 회원(<code>AGE&gt;=20 AND AGE&lt;=29</code>) 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용한다.</p>
<h3 id="🟩-12세-이하인-여자-환자-목록-출력하기">🟩 12세 이하인 여자 환자 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/132201">https://school.programmers.co.kr/learn/courses/30/lessons/132201</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT PT_NAME, PT_NO, GEND_CD, AGE, IFNULL(TLNO, &#39;NONE&#39;)
  FROM PATIENT
  WHERE AGE&lt;=12 AND GEND_CD=&#39;W&#39;
  ORDER BY AGE DESC, PT_NO ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>PATIENT</code> 테이블에서 모든 열 이름인 환자이름(<code>PT_NAME</code>), 환자번호(<code>PT_NO</code>), 성별코드(<code>GEND_CD</code>), 나이(<code>AGE</code>), 전화번호(<code>TLNO</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 전화번호(<code>TLNO</code>)가 없는 경우에는 &#39;NONE&#39;으로 출력하기 위해 <code>IFNULL(열이름,대체값)</code>함수를 사용한다. 이때 12세 이하(<code>AGE&lt;=12</code>)인 여자환자(<code>GEND_CD=&#39;W&#39;</code>) 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 나이(<code>AGE</code>)를 기준으로 내림차순(<code>DESC</code>) 정렬하고, 나이 같다면 환자 번호(<code>PT_NO</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<h3 id="🟩-흉부외과-또는-일반외과-의사-목록-출력하기">🟩 흉부외과 또는 일반외과 의사 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/132203">https://school.programmers.co.kr/learn/courses/30/lessons/132203</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT DR_NAME, DR_ID, MCDP_CD, DATE_FORMAT(HIRE_YMD, &#39;%Y-%m-%d&#39;) AS HIRE_YMD
  FROM DOCTOR
  WHERE MCDP_CD=&#39;CS&#39; OR MCDP_CD=&#39;GS&#39;
  ORDER BY HIRE_YMD DESC, DR_NAME ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>DOCTOR</code> 테이블에서 의사이름(<code>DR_NAME</code>), 의사ID(<code>DR_ID</code>), 진료과(<code>MCDP_CD</code>), 고용일자(<code>HIRE_YMD</code>)를 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, <code>DATE_FORMAT(date, format)</code>함수를 사용하여 고용일자를 년-월-일(<code>&#39;%Y-%m-%d&#39;</code>)만 나타나게 한다. 이때 진료과(<code>MCDP_CD</code>)가 흉부외과(<code>CS</code>)이거나 일반외과(<code>GS</code>) 조건을 추가하기 위해 <code>WHERE 조건</code>절을 사용한다. 또한 <code>ORDER BY</code>절을 사용하여 고용일자(<code>HIRE_YMD</code>)를 기준으로 내림차순(<code>DESC</code>) 정렬하고, 고용일자가 같다면 이름(<code>DR_NAME</code>)을 기준으로 오름차순(<code>ASC</code>) 정렬한다.</p>
<hr>
<h2 id="📌-level-2">📌 Level 2</h2>
<h3 id="🟩-3월에-태어난-여성-회원-목록-출력하기">🟩 3월에 태어난 여성 회원 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131120">https://school.programmers.co.kr/learn/courses/30/lessons/131120</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT MEMBER_ID, MEMBER_NAME, GENDER, DATE_FORMAT(DATE_OF_BIRTH, &#39;%Y-%m-%d&#39;) AS DATE_OF_BIRTH
  FROM MEMBER_PROFILE
  WHERE MONTH(DATE_OF_BIRTH) = &#39;3&#39; AND GENDER = &#39;W&#39; AND TLNO != &#39;NULL&#39;
  ORDER BY MEMBER_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>MEMBER_PROFILE</code> 테이블에서 회원의 ID(<code>MEMBER_ID</code>), 이름(<code>MEMBER_NAME</code>), 성별(<code>GENDER</code>), 생년월일(<code>DATE_OF_BIRTH</code>)을 조회하기 위해 <code>SELECT~FROM</code>문을 사용하고, 생년월일을 출력하기 위해 <code>DATE_FORMAT(칼럼 이름, 날짜 형식)</code>구문을 활용한다.
또한 회원 중에서 생일이 3월(<code>MONTH(DATE_OF_BIRTH) = &#39;3&#39;</code>)인 여성(<code>GENDER = &#39;W&#39;</code>)이고, 전화번호가 NULL인 경우를 제외(<code>TLNO != &#39;NULL&#39;</code>)하여 조회하기 위해 <code>WHERE 조건</code>절을 사용한다. 추가적으로 <code>ORDER BY</code>절을 추가하여 회원의 ID(<code>MEMBER_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬을 한다.</p>
<h3 id="🟩-재구매가-일어난-상품과-회원-리스트-구하기">🟩 재구매가 일어난 상품과 회원 리스트 구하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131536">https://school.programmers.co.kr/learn/courses/30/lessons/131536</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT USER_ID, PRODUCT_ID
  FROM ONLINE_SALE
  GROUP BY USER_ID, PRODUCT_ID
  HAVING COUNT(*) &gt;= 2
  ORDER BY USER_ID ASC, PRODUCT_ID DESC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>ONLINE_SALE</code> 테이블에서 재구매한 회원 ID(<code>USER_ID</code>)와 재구매한 상품 ID(<code>PRODUCT_ID</code>)를 출력하기 위해 <code>SELECT~FROM</code>문을 사용한다. 이때 동일한 회원(<code>USER_ID</code>)이 동일한 상품(<code>PRODUCT_ID</code>)을 재구매한 데이터를 구하기 위해 <code>GROUP BY</code>절과 <code>HAVING 조건</code>절을 사용한다. 추가적으로 <code>ORDER BY</code>절을 추가하여 회원 ID(<code>USER_ID</code>)를 기준으로 오름차순(<code>ASC</code>) 정렬하고, 회원 ID가 같다면 상품 ID(<code>PRODUCT_ID</code>)를 기준으로 내림차순(<code>DESC</code>) 정렬을 한다.</p>
<hr>
<h2 id="📌-level-4">📌 Level 4</h2>
<h3 id="🟩-서울에-위치한-식당-목록-출력하기">🟩 서울에 위치한 식당 목록 출력하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131118">https://school.programmers.co.kr/learn/courses/30/lessons/131118</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT I.REST_ID, I.REST_NAME, I.FOOD_TYPE, I.FAVORITES, I.ADDRESS, ROUND(AVG(R.REVIEW_SCORE), 2) AS SCORE
  FROM REST_INFO I
  JOIN REST_REVIEW R
  ON I.REST_ID = R.REST_ID
  WHERE I.ADDRESS LIKE &#39;서울%&#39;
  GROUP BY I.REST_ID
  ORDER BY SCORE DESC, I.FAVORITES DESC;</code></pre>
<p><strong>3. 코드 해석</strong>
해당 문제는 <code>REST_INFO</code> 테이블과 <code>REST_REVIEW</code>에서 <code>REST_ID</code>로 내부 조인(<code>INNER JOIN</code>)을 하고(<code>SELECT~FROM~JOIN~ON</code>), 서울에 위치한 식당들만(<code>ADDRESS LIKE &#39;서울%&#39;</code>)을 <code>WHERE조건</code>절로 조회한다.
이때 <code>REST_INFO</code> 테이블의 식당 ID(<code>REST_ID</code>), 식당 이름(<code>REST_NAME</code>), 음식 종류(<code>FOOD_TYPE</code>), 즐겨찾기수(<code>FAVORITES</code>), 주소(<code>ADDRESS</code>)와 <code>REST_REVIEW</code>의 리뷰 점수(<code>REVIEW_SCORE</code>)의 평균인 리뷰 평균 점수(<code>SCORE</code>)를 조회한다. 리뷰 평균 점수(<code>SCORE</code>)는 소수점 세 번째 자리에서 반올림하기 위해 <code>ROUND(숫자, 반올림 할 자리수)</code> 함수를 사용한다. 이것은 <code>GROUP BY</code>절을 사용하기 때문에 <code>REST_ID</code>별 리뷰 평균 점수를 구할 수 있다.
추가적으로 <code>ORDER BY</code>절을 추가하여 평균점수(<code>SCORE</code>)를 기준으로 내림차순(<code>DESC</code>) 정렬하고, 평균점수가 같다면 즐겨찾기수(<code>FAVORITES</code>)를 기준으로 내림차순(<code>DESC</code>) 정렬을 한다.</p>
<h3 id="🟩-오프라인온라인-판매-데이터-통합하기">🟩 오프라인/온라인 판매 데이터 통합하기</h3>
<p><strong>1. 문제 link</strong> <a href="https://school.programmers.co.kr/learn/courses/30/lessons/131537">https://school.programmers.co.kr/learn/courses/30/lessons/131537</a>
<strong>2. 코드</strong></p>
<pre><code class="language-sql">SELECT DATE_FORMAT(A.SALES_DATE, &quot;%Y-%m-%d&quot;) AS SALES_DATE, A.PRODUCT_ID, A.USER_ID, A.SALES_AMOUNT
FROM ONLINE_SALE A
WHERE YEAR(A.SALES_DATE) = 2022 AND MONTH(A.SALES_DATE) = 3
UNION ALL
SELECT DATE_FORMAT(B.SALES_DATE, &quot;%Y-%m-%d&quot;) AS SALES_DATE, B.PRODUCT_ID, NULL AS USER_ID, B.SALES_AMOUNT
FROM OFFLINE_SALE B
WHERE YEAR(B.SALES_DATE) = 2022 AND MONTH(B.SALES_DATE) = 3
ORDER BY SALES_DATE ASC, PRODUCT_ID ASC, USER_ID ASC;</code></pre>
<p><strong>3. 코드 해석</strong>
<code>UNION ALL</code></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-6]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-6</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-6</guid>
            <pubDate>Wed, 12 Oct 2022 09:30:19 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-7강-스토어드-프로시저">📌 7강 스토어드 프로시저</h2>
<h3 id="✔️-07-1-스토어드-프로시저-사용-방법">✔️ 07-1 스토어드 프로시저 사용 방법</h3>
<ul>
<li><p><strong>스토어드 프로시저</strong>: MySQL에서 제공하는 프로그래밍 기능, 쿼리 문의 집합</p>
<ul>
<li>SQL에 프로그래밍 기능을 추가해서 일반 프로그래밍 언어와 비슷한 효과를 낼 수 있음</li>
</ul>
</li>
<li><p><strong>스토어드 프로시저 형식</strong></p>
<ul>
<li><code>DELIMITER</code>: 구분자</li>
<li>스토어드 프로시저의 이름에 <code>_proc</code>(procedure의 의미)를 붙임</li>
<li><code>IN</code> 또는 <code>OUT</code> 매개변수: 입력 또는 출력 매개변수</li>
<li><code>CREATE PROCEDURE</code>: 스토어드 프로시저를 만드는 것으로 실행(호출)한 것은 아님<pre><code class="language-sql">DELIMITER $$
CREATE PROCEDURE 스토어드_프로시저_이름(IN 또는 OUT 매개변수)
BEGIN
이 부분에 SQL 프로그래밍을 코드를 작성
END $$
DELIMITER ;</code></pre>
</li>
</ul>
</li>
<li><p><strong>스토어드 프로시저 실행(호출) 형식</strong></p>
<pre><code class="language-sql">CALL 스토어드_프로시저_이름();</code></pre>
</li>
<li><p><strong>스토어드 프로시저의 생성</strong></p>
<pre><code class="language-sql">USE 데이터베이스_이름; -- 데이터베이스 사용
DROP PROCEDURE IF EXISTS 스토어드_프로시저_이름; -- 해당 이름의 스토어드 프로시저가 있다면 삭제
DELIMITER $$
CREATE PROCEDURE 스토어드_프로시저_이름(IN 또는 OUT 매개변수)
BEGIN
  이 부분에 SQL 프로그래밍을 코드를 작성
END $$
DELIMITER ; -- 스토어드 프로시저 만들기
CALL 스토어드_프로시저_이름(); -- 스토어드 프로시저 호출</code></pre>
</li>
<li><p><strong>스토어드 프로시저의 삭제</strong></p>
<pre><code class="language-sql">DROP PROCEDURE 스토어드_프로시저_이름;</code></pre>
</li>
<li><p><strong>매개변수의 사용</strong></p>
<ul>
<li><strong><span style='color:blue'>입력 매개변수</span> 지정 형식</strong><pre><code>IN 입력_매개변수_이름 데이터_형식</code></pre></li>
<li><strong><span style='color:blue'>입력 매개변수</span>가 있는 스토어드 프로시저 실행</strong><pre><code>CALL 프로시저_이름(전달_값);</code></pre></li>
<li><strong><span style='color:blue'>출력 매개변수</span> 지정 형식</strong><pre><code>OUT 출력_매개변수_이름 데이터_형식</code></pre></li>
<li><strong><span style='color:blue'>출력 매개변수</span>가 있는 스토어드 프로시저 실행</strong><pre><code>CALL 프로시저_이름(@변수명);
SELECT @변수명;</code></pre></li>
</ul>
</li>
<li><p><strong>날짜와 관련된 MySQL 함수</strong></p>
<ul>
<li><code>YEAR(날짜)</code> : 연</li>
<li><code>MONTH(날짜)</code> : 월</li>
<li><code>DAY(날짜)</code> : 일</li>
<li><code>CURDATE()</code> 함수 : 현재 날짜<pre><code class="language-sql">SELECT YEAR(CURDATE()), MONTH(CURDATE()), DAY(CURDATE());</code></pre>
</li>
</ul>
</li>
<li><p><strong>동적 SQL</strong>: 다이나믹하게 SQL을 생성한 후 실행함, <code>PREPARE</code> 문과 <code>EXECUTE</code> 문을 사용함</p>
<pre><code class="language-sql">PREPARE
EXECUTE
DEALLOCATE PREPARE</code></pre>
<h3 id="✔️-07-2-스토어드-함수와-커서">✔️ 07-2 스토어드 함수와 커서</h3>
</li>
<li><p><strong>스토어드 함수</strong>: MySQL에서 제공하는 내장 함수 외에 직접 함수를 만드는 기능을 제공</p>
</li>
<li><p><strong>스토어드 함수의 사용</strong></p>
<ul>
<li>SQL로 스토어드 함수 생성 권한을 허용해주는 구문<pre><code class="language-sql">SET GLOBAL log_bin_trust_function_creators = 1;</code></pre>
</li>
</ul>
</li>
<li><p><strong>스토어드 함수의 형식</strong></p>
<ul>
<li><p><code>RETURNS</code> 문: 반환할 값의 데이터 형식을 지정</p>
</li>
<li><p><code>RETURN</code> 문: 하나의 값을 반환</p>
</li>
<li><p>스토어드 함수의 매개변수는 모두 <code>입력 매개변수</code>이기 때문에 <span style='color:red'><code>IN</code>을 붙이지 않음</span></p>
</li>
<li><p>스토어드 함수 호출은 <code>SELECT</code> 문</p>
</li>
<li><p><span style='color:red'>스토어드 함수안에서 <code>SELECT</code>를 사용할 수 없음</span></p>
<pre><code class="language-sql">DELIMITER $$
CREATE FUNCTION 스토어드_함수_이름(매개변수)
RETURNS 반환형식
BEGIN

이 부분에 프로그래밍 코딩
RETURN 반환값;
</code></pre>
</li>
</ul>
<p>END $$
DELIMITER ;
SELECT 스토어드_함수_이름();
```</p>
</li>
<li><p><strong>스토어드 함수의 내용 확인</strong></p>
<pre><code class="language-sql">SHOW CREATE FUNCTION 함수_이름;</code></pre>
</li>
<li><p><strong>스토어드 함수의 삭제</strong></p>
<pre><code class="language-sql">DROP FUNCTION 스토어드_함수_이름;</code></pre>
</li>
</ul>
<hr>
<ul>
<li><p><strong>커서</strong>: 첫 번째 행을 처리한 후에 마지막 행까지 한 행씩 접근해서 값을 처리</p>
<ul>
<li><strong>커서 작동 순서</strong>
1) 커서 선언하기
2) 반복 조건 선언하기
3) 커서 열기
4) 데이터 가져오기 -&gt; 데이터 처리하기: 이 부분을 반복
5) 커서 닫기</li>
</ul>
</li>
<li><p><strong>커서의 단계별 실습</strong></p>
<ul>
<li><p><span style='color:red'>1) 사용할 변수 준비하기</span></p>
<ul>
<li><code>DEFAULT</code> 문: 초기값을 설정하기<pre><code class="language-sql">DECLARE 변수명 데이터형식 (DEFAULT 숫자);</code></pre>
</li>
<li><code>endOfRow</code>: 행의 끝을 파악하기<pre><code class="language-sql">DECLARE endOfRow BOOLEAN DEFAULT FALSE;</code></pre>
</li>
</ul>
</li>
<li><p><span style='color:red'>2) 커서 선언하기</span></p>
<ul>
<li>커서라는 것은 결국 <code>SELECT</code> 문임<pre><code class="language-sql">DECLARE 커서_이름 CURSOR FOR
  SELECT 열_이름 FROM 테이블_이름;</code></pre>
</li>
</ul>
</li>
<li><p><span style='color:red'>3) 반복 조건 선언하기</span></p>
<ul>
<li><code>DECLARE CONTINUE HANDLER</code>: 반복 조건을 준비하는 예약어</li>
<li><code>FOR NOT FOUND</code>: 더 이상 행이 없을 때 이어진 문장을 수행함 (행이 끝나면 endOfRow에 TRUE를 대입함)<pre><code class="language-sql">DECLARE CONTINUE HANDLER
  FOR NOT FOUND SET endOfRow = TRUE;</code></pre>
</li>
</ul>
</li>
<li><p><span style='color:red'>4) 커서 열기</span></p>
<pre><code class="language-sql">OPEN 커서_이름;</code></pre>
</li>
<li><p><span style='color:red'>5) 행 반복하기</span></p>
<ul>
<li><p><code>cursor_loop</code>: 반복할 부분의 이름을 지정한 것</p>
<pre><code class="language-sql">cursor_loop: LOOP
이 부분을 반복
END LOOP cursor_loop;</code></pre>
</li>
<li><p><code>LEAVE</code>: 반복할 이름을 빠져나감</p>
</li>
<li><p><code>FETCH</code>: 한 행씩 읽어오는 것</p>
<pre><code class="language-sql">cursor_loop: LOOP
FETCH 커서_이름 INTO 변수; -- 한 행씩 읽어오기

IF endOfRow THEN
  LEAVE cursor_loop;
END IF; -- 행의 끝에 다다르면 반복하는 부분을 빠져나감

SET 변수; -- 변수의 누적
END LOOP cursor_loop;</code></pre>
</li>
</ul>
</li>
<li><p><span style='color:red'>6) 커서 닫기</span></p>
<pre><code class="language-sql">CLOSE 커서_이름;</code></pre>
</li>
</ul>
</li>
<li><p>커서는 스토어드 프로시저 안에 코드를 작성함</p>
<ul>
<li>스토어드 프로시저를 실행하면 커서가 작동됨<h3 id="✔️-07-3-자동-실행되는-트리거">✔️ 07-3 자동 실행되는 트리거</h3>
</li>
</ul>
</li>
<li><p><strong>트리거</strong>: 테이블에 <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code> 작업이 발생하면 실행되는 코드</p>
<ul>
<li>사전적 의미: &#39;방아쇠&#39;</li>
<li>트리거는 테이블에 무슨 일이 일어나면 자동으로 실행됨</li>
<li>자동으로 수행하여 사용자가 추가 작업을 잊어버리는 실수를 방지함</li>
<li><span style='color:red'>데이터의 무결성</span>: 데이터에 오류가 발생하는 것을 막는 것</li>
</ul>
</li>
<li><p><strong>트리거의 기본 작동</strong></p>
<ul>
<li><p>트리거는 테이블에서 <code>DML</code> 문 (<code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code> 등)의 이벤트가 발생할 때 작동함</p>
</li>
<li><p>테이블에 미리 부착되는 프로그램 코드: <code>AFTER 트리거</code>, <code>BEFORE 트리거</code></p>
</li>
<li><p>트리거는 <code>IN</code>, <code>OUT</code> 매개변수를 사용할 수 없음</p>
</li>
<li><p><span style='color:red'>1) 테이블 만들기</span></p>
<pre><code class="language-sql">USE 데이터베이스_이름;
CREATE TABLE IF NOT EXISTS 테이블_이름(열_이름1 데이터형식, 열_이름2 데이터형식, ...)
INSERT INTO 테이블_이름 VALUES(데이터, 데이터, ...);</code></pre>
</li>
<li><p><span style='color:red'>2) 테이블에 트리거를 부착하기</span></p>
<pre><code class="language-sql">DROP TRIGGER IF EXISTS 트리거_이름;
DELIMITER $$
CREATE TRIGGER 트리거_이름
  AFTER DELETE -- 삭제(DELETE) 후에 작동하도록 지정
  ON 테이블_이름 -- 트리거를 부착할 테이블
  FOR EACH ROW
BEGIN
  트리거 실행 시 작동되는 코드들
END $$
DELIMITER ;</code></pre>
</li>
<li><p><span style='color:red'>3) <code>INSERT</code> 문, <code>UPDATE</code> 문, <code>DELETE</code> 문</span></p>
<pre><code class="language-sql">SET @msg = &#39;&#39;;
INSERT INTO 테이블_이름 VALUES(데이터, 데이터, ...); -- 삽입
SELECT @msg;
UPDATE 테이블_이름 SET 열_이름=데이터 WHERE 조건; -- 수정
SELECT @msg;
DELETE FROM 테이블_이름 WHERE 조건; -- 삭제(DELETE)에 트리거 작동
SELECT @msg;</code></pre>
</li>
</ul>
</li>
<li><p><strong>트리거 활용</strong>: 테이블에 입력/수정/삭제되는 정보를 백업하는 용도로 활용</p>
<ul>
<li>테이블에 이벤트가 먼저 적용된 후에 트리거가 실행됨</li>
<li>백업 테이블: 테이블에 <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code> 작업이 일어나는 경우, 변경되기 전의 데이터를 저장할 테이블</li>
<li><code>AFTER INSERT</code>: <code>INSERT 트리거</code>는 테이블에서 <code>INSERT</code> 문의 이벤트가 발생될 때만 작동</li>
<li><code>AFTER UPDATE</code>: <code>UPDATE 트리거</code>는 테이블에서 <code>UPDATE</code> 문의 이벤트가 발생될 때만 작동</li>
<li><code>AFTER DELETE</code>: <code>DELETE 트리거</code>는 테이블에서 <code>DELETE</code> 문의 이벤트가 발생될 때만 작동</li>
</ul>
</li>
<li><p><strong>테이블의 모든 행 데이터 삭제</strong>: <code>DELETE</code> 와 <code>TRUNCATE TABLE</code> 문</p>
<ul>
<li><code>DELETE 트리거</code>는 오직 <code>DELETE</code>문에만 작동하기 때문에 <code>TRUNCATE TABLE</code>로 삭제 시에는 트리거가 작동하지 않음<pre><code class="language-sql">DELETE FROM 테이블_이름;
TRUNCATE TABLE 테이블_이름;</code></pre>
</li>
</ul>
</li>
<li><p><strong>트리거가 사용하는 임시 테이블</strong></p>
<ul>
<li>MySQL이 알아서 생성 및 관리</li>
<li>테이블에 <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code> 작업이 수행되면 임시로 사용되는 시스템 테이블: <code>NEW 테이블</code>과 <code>OLD 테이블</code></li>
<li>트리거에서 기존 데이터는 <code>OLD 테이블</code>에, 새로운 데이터는 <code>NEW 테이블</code>에 잠깐 저장됨<ul>
<li><code>NEW 테이블</code>: INSERT(새 값) 형태로 실행되면 작동</li>
<li><code>OLD 테이블</code>: DELETE(예전 값) 형태로 실행되면 작동</li>
<li><code>NEW 테이블</code>과 <code>OLD 테이블</code> 모두 사용: UPDATE(새 값, 예전 값) 형태로 실행되면 작동</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고문헌">📌 참고문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p330-p368.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-5]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-5</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-5</guid>
            <pubDate>Tue, 11 Oct 2022 15:36:23 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-6강-인덱스">📌 6강 인덱스</h2>
<h3 id="✔️-06-1-인덱스-개념">✔️ 06-1 인덱스 개념</h3>
<ul>
<li><strong>인덱스(index)</strong>: 데이터를 빠르게 찾을 수 있도록 도와주는 도구<ul>
<li>책 뒤의 &#39;찾아보기&#39;=&#39;색인&#39;, &#39;인덱스&#39;</li>
<li><strong>인덱스의 문제점</strong>: 필요 없는 인덱스를 만들면 데이터베이스가 차지하는 공간만 더 늘고, 인덱스를 이용해서 데이터를 찾는 것이 전체 테이블을 찾아보는 것보다 느려질 수 있음</li>
<li><U>데이터베이스에 인덱스를 생성해 놓아도,</U> 인덱스를 사용해서 검색하는 것이 빠를지 아니면 전체 테이블을 검색하는 것이 빠를지 <U>MySQL이 알아서 판단함</U></li>
<li><strong>인덱스의 장점과 단점</strong><ul>
<li><strong>장점</strong>: SELECT 문으로 검색하는 속도가 매우 빨라짐, 그 결과 컴퓨터의 부담이 줄어들어서 결국 전체 시스템의 성능이 향상됨</li>
<li><strong>단점</strong>: 인덱스도 공간을 차지해서 데이터베이스 안에 추가적인 공간이 필요함, 처음에 인덱스를 만드는 데 시간이 오래 걸릴 수 있음, SELECT가 아닌 데이터의 변경 작업(INSERT, UPDATE, DELETE)이 일어나면 오히려 성능이 나빠질 수도 있음</li>
</ul>
</li>
<li><strong>클러스터형 인덱스</strong>: 기본 키로 지정하면 자동 생성되고 테이블에 1개만 만들 수 있음, 기본 키로 지정한 열을 기준으로 자동 정렬됨<ul>
<li>기본 키(PRIMARY)로 지정하면 자동으로 해당 열에 클러스터형 인덱스가 생성됨(기본 키는 테이블에 하나만 지정 가능)</li>
<li>자동으로 <U>정렬</U>되는 클러스터형 인덱스(클러스터형 인덱스가 생성된 열로 데이터가 자동 정렬됨)</li>
</ul>
</li>
<li><strong>보조 인덱스</strong>: 고유 키로 지정하면 자동 생성되고 여러 개를 만들 수도 있지만 자동 정렬되지 않음<ul>
<li>고유 키(UNIQUE)로 지정하면 자동으로 해당 열에 보조 인덱스가 생성됨(고유 키는 테이블에 여러 개 지정 가능)</li>
<li>정렬되지 않는 보조 인덱스(보조 인덱스를 생성해도 데이터의 내용이나 순서는 변경되지 않음)</li>
<li>보조 인덱스는 여러 개 생성할 수 있지만 데이터베이스의 공간을 차지하므로 꼭 필요한 열에만 적절히 보조 인덱스를 생성할 것!</li>
</ul>
</li>
<li><strong>SHOW INDEX 문</strong>: 테이블의 인덱스 정보 확인(Key_name, Column_name)<ul>
<li>Non_Unique 부분: 고유하지 않다는 의미로 중복이 허용되는가?(0은 False, 1은 True)</li>
<li>Key_name 부분: PRIMARY(기본 키)나 열 이름</li>
<li>Column_name 부분: 인덱스가 만들어진 해당 열의 이름<pre><code class="language-sql">SHOW INDEX FROM 테이블_이름;</code></pre>
</li>
</ul>
</li>
<li><strong>고유 인덱스</strong>: 인덱스의 값이 중복되지 않는다<ul>
<li>기본 키나 고유 키로 지정하면 고유 인덱스가 생성됨</li>
<li>그 외의 인덱스는 <strong>단순 인덱스</strong><h3 id="✔️-06-2-인덱스의-내부-작동">✔️ 06-2 인덱스의 내부 작동</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>균형 트리</strong>: &#39;자료 구조&#39;에 나오는 범용적으로 사용되는 데이터의 구조<ul>
<li>트리에서 뿌리(루트), 줄기(중간), 잎(리프)</li>
</ul>
</li>
<li><strong>균형 트리 구조</strong><ul>
<li>균형 트리는 데이터를 검색할 때(SELECT 문) 아주 뛰어난 성능을 발휘함</li>
<li><strong>노드</strong>: 데이터가 저장되는 공간<ul>
<li>루프 노드: 노드의 가장 상위 노드</li>
<li>중간 노드: 루트 노드와 리프 노드의 중간에 끼인 노드들</li>
<li>리프 노드: 제일 마지막에 존재하는 노드</li>
</ul>
</li>
<li><span style='color:red'> 노드는 MySQL에서 <strong>페이지</strong>라고 부름</span><ul>
<li>페이지는 최소한의 저장 단위 = 16Kbyte(16384byte) 크기</li>
</ul>
</li>
<li><span style='color:blue'>균형 트리 예시</span>
1) <strong>루트 페이지</strong> 검색
2) <strong>리프 페이지</strong>로 이동 후 검색</li>
<li>페이지 분할: 새로운 페이지를 준비해서 데이터를 나누는 작업<ul>
<li>인덱스를 구성하면 데이터 변경 작업(INSERT, UPDATE, DELETE)시 성능이 나빠짐(입력이 느려짐)</li>
<li>페이지 분할이 일어나면 MySQL이 느려지고, 너무 자주 일어나면 성능에 큰 영향을 줌</li>
</ul>
</li>
<li><span style='color:blue'>페이지 분할 예시</span>
1) 새로운 데이터 INSERT된다고 가정
2) 새로운 삽입으로 인해 <strong>리프 페이지</strong>의 페이지 분할 작업이 일어남
3) 루트 페이지의 페이지 분할 작업으로 <strong>중간 페이지</strong>가 형성됨
4) 새로운 <strong>루트 페이지</strong> 생성</li>
</ul>
</li>
<li><strong>전체 테이블 검색(Full Table Scan)</strong>: 데이터를 처음부터 끝까지 검색하는 것</li>
<li><strong>인덱스의 구조</strong><ul>
<li><strong>클러스터형 인덱스 구성</strong><ul>
<li>데이터 페이지가 정렬되고 균형 트리 형태의 인덱스가 형성됨<ul>
<li>클러스터형 인덱스는 <span style='color:blue'>영어사전</span>과 같음(영어사전은 알파벳 순서로 구성된 찾아보기)</li>
</ul>
</li>
<li>각 페이지의 인덱스로 지정된 열의 첫 번째 값을 가지고 루트 페이지를 만듦</li>
<li>인덱스 페이지의 리프 페이지는 데이터 그 자체임</li>
</ul>
</li>
<li><strong>보조 인덱스 구성</strong><ul>
<li>보조 인덱스는 데이터 페이지를 건드리지 않음, 별도의 장소에 인덱스 페이지를 생성<ul>
<li>보조 인덱스는 <span style='color:blue'>일반 책의 찾아보기</span>와 같은 개념</li>
</ul>
</li>
<li>데이터의 위치는 <span style='color:red'>페이지 번호+#위치</span>로 기록됨</li>
</ul>
</li>
</ul>
</li>
<li><strong>인덱스 검색</strong>: 클러스터형 또는 보조 인덱스를 이용해서 데이터를 검색하는 것으로 속도는 인덱스를 사용하지 않았을 때보다 빠름<ul>
<li><strong>클러스터형 인덱스에서 데이터 검색</strong>
1) 가장 먼저 루트 페이지는 읽음
2) 리프 페이지(=데이터 페이지) 읽음</li>
<li><strong>보조 인덱스에서 데이터 검색</strong>
1) 가장 먼저 루트 페이지는 읽음
2) 리프 페이지 읽음
3) 데이터 페이지 읽음<h3 id="✔️-06-3-인덱스의-실제-사용">✔️ 06-3 인덱스의 실제 사용</h3>
</li>
</ul>
</li>
<li><strong>인덱스 생성 문법</strong>: <code>PRIMARY KEY</code> 문법, <code>UNIQUE</code> 문법, <code>CREATE INDEX</code>문<ul>
<li><code>PRIMARY KEY</code> 문법은 클러스터형 인덱스</li>
<li><code>UNIQUE</code> 문법은 보조 인덱스</li>
<li><code>CREATE INDEX</code> 문으로 생성되는 인덱스는 보조 인덱스임</li>
<li><code>UNIQUE</code>: 중복이 안 되는 고유 인덱스를 만드는 것, 생략시 중복 허용됨</li>
<li><code>ASC 또는 DESC</code>: 인덱스의 오름차순(<code>ASC</code>) 또는 내림차순(<code>DESC</code>)<pre><code class="language-sql">CREATE [UNIQUE] INDEX 인덱스_이름
ON 테이블_이름 (열_이름) [ASC| DESC]</code></pre>
</li>
</ul>
</li>
<li><strong>인덱스 제거 문법</strong>: <code>DROP INDEX</code>문<ul>
<li>기본 키, 고유 키로 자동 생성된 인덱스는 <code>DROP INDEX</code>로 제거하지 못함<ul>
<li>클러스터형 인덱스와 보조 인덱스가 섞여 있을 때는 보조 인덱스를 먼저 제거하는 것이 좋음<ul>
<li>클러스터형 인덱스를 먼저 제거해도 되지만, 데이터를 쓸데없이 재구성해서 시간이 더 오래 걸림</li>
</ul>
</li>
<li><code>ALTER TABLE</code> 문으로 기본 키나 고유 키를 제거하면 자동으로 생성된 인덱스도 제거할 수 있음</li>
<li>기본 키를 제거하려면 먼저 관련된 외래 키를 제거해야 함<pre><code class="language-sql">DROP INDEX 인덱스_이름 ON 테이블_이름</code></pre>
</li>
</ul>
</li>
<li><strong>외래 키 이름</strong>: <code>information_schema</code> 데이터베이스의 <code>referential_constraints</code> 테이블 조회<pre><code class="language-sql">SELECT table_name, constraint_name
  FROM information_schema.referential_constraints
  WHERE constraint_schema = &#39;데이터베이스_이름&#39;;</code></pre>
</li>
<li><strong>먼저 외래 키 제거, 기본 키 제거</strong><pre><code class="language-sql">ALTER TABLE 테이블_이름
  DROP FOREIGN KEY 열_이름; -- 외래 키 제거
ALTER TABLE 테이블_이름
  DROP PRIMARY KEY; -- 기본 키 제거</code></pre>
</li>
</ul>
</li>
<li><strong>인덱스 정보</strong>: <code>SHOW INDEX</code> 문<pre><code class="language-sql">SHOW INDEX FROM 테이블_이름</code></pre>
</li>
<li><strong>인덱스의 크기</strong>: <code>SHOW TABLE STATUS</code> 문<ul>
<li>테이블에 생성된 인덱스의 크기 확인<pre><code class="language-sql">SHOW TABLE STATUS LIKE &#39;테이블_이름&#39;</code></pre>
</li>
</ul>
</li>
<li><strong>생성한 인덱스 실제 적용하기</strong>: <code>ANALYZE TABLE</code> 문<pre><code class="language-sql">ANALYZE TABLE 테이블_이름 -- 지금까지 만든 인덱스를 모두 적용하기</code></pre>
</li>
<li><strong>인덱스의 활용</strong>: <code>SELECT ~ FROM ~ WHERE</code> 문<ul>
<li><code>[Execution Plan] 창</code>에서 <code>Full Table Scan</code>을 제외하고 나머지는 모두 인덱스를 사용했다는 의미</li>
<li><code>WHERE</code> 문에서 열에 연산이 가해지면 인덱스를 사용하지 않음<pre><code class="language-sql">SELECT 열_이름
FROM 테이블_이름 
WHERE 조건</code></pre>
</li>
</ul>
</li>
<li><strong>인덱스를 효과적으로 사용하는 방법</strong><ul>
<li>인덱스는 열 단위에 생성됨</li>
<li>WHERE 절에서 사용되는 열에 인덱스를 만들어야 함</li>
<li>WHERE 절에 사용되더라도 자주 사용해야 가치가 있음</li>
<li>데이터의 중복이 높은 열은 인덱스를 만들어도 별 효과가 없음</li>
<li>클러스터형 인덱스는 테이블 당 하나만 생성할 수 있음</li>
<li>사용하지 않는 인덱스는 제거함</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고문헌">📌 참고문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p274-p326.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-4]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-4</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-4</guid>
            <pubDate>Sun, 09 Oct 2022 18:47:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-5강-테이블과-뷰">📌 5강 테이블과 뷰</h2>
<h3 id="✔️-05-1-테이블-만들기">✔️ 05-1 테이블 만들기</h3>
<ul>
<li>데이터베이스와 테이블 설계<ul>
<li>MySQL 워크벤치를 이용하여 테이블을 만드는 방법</li>
<li><strong>테이블</strong>: 표 형태로 구성된 2차원 구조, 행과 열<ul>
<li>행(=로우 or 레코드)</li>
<li>열(=컬럼 or 필드)</li>
</ul>
</li>
<li><span style='color:blue'>예시</span>: 쇼핑몰 데이터베이스인 &#39;네이버 쇼핑&#39; 데이터베이스 구조 ➡️ 회원 테이블(member), 구매 테이블(buy)</li>
<li><strong>각 열에 가장 적합한 <span style='color:red'>데이터 형식</span> 지정</strong><ul>
<li>회원 테이블(member)
<img src="https://velog.velcdn.com/images/so-kr/post/509bffdd-e3cc-43d9-9f0d-11d01f7e6537/image.png" alt=""></li>
<li>구매 테이블(buy)
<img src="https://velog.velcdn.com/images/so-kr/post/388a6352-84a1-45d9-89b2-3bf70cacc22a/image.png" alt=""></li>
</ul>
</li>
</ul>
</li>
<li>MySQL 워크벤치의 <strong>GUI 환경</strong>에서 테이블 만들기(p.219-p.224 참고)<ul>
<li>GUI(=Graphical User Interface): 윈도에서 진행하는 작업을 의미 
1) 데이터베이스 생성하기
2) 테이블 생성하기
3) 데이터 입력하기</li>
</ul>
</li>
<li>MySQL 워크벤치의 <strong>SQL</strong>로 테이블 만들기
<strong>1) 데이터베이스 생성하기: <span style='color:blue'><code>CREATE DATABASE</code></span></strong><pre><code class="language-sql">DROP DATABASE IF EXISTS 데이터베이스_이름; -- 기존 해당 데이터베이스가 있다면 삭제
CREATE DATABASE 데이터베이스_이름; - 데이터베이스 생성</code></pre>
<strong>2) 테이블 생성하기: <span style='color:blue'><code>CREATE TABLE</code></span></strong><ul>
<li>테이블에 열_이름과 데이터형식 지정</li>
<li>_&lt;테이블 옵션 추가&gt;_<ol>
<li><code>NULL</code>(or <code>NOT NULL</code>) 지정</li>
<li><code>PRIMARY KEY</code> 설정(기본 키 설정)</li>
<li><code>AUTO_INCREMENT</code> 설정(자동 증가)</li>
</ol>
</li>
<li>외래 키는 테이블을 만들 때 제일 마지막에 <code>FOREIGN KEY</code> 예약어로 지정하기<pre><code class="language-sql">USE 데이터베이스_이름;
DROP TABLE IF EXISTS 테이블_이름; -- 기존 해당 테이블이 있다면 삭제
CREATE TABLE 테이블_이름
( 열_이름1 데이터형식 AUTO_INCREMENT(자동 증가 설정) NULL(or NOT NULL) PRIMARY KEY(기본 키 설정),
열_이름2 데이터형식 NULL(or NOT NULL) ,
열_이름3 데이터형식 NULL(or NOT NULL) ,
...
FOREIGN KEY(열_이름) REFERENCES 테이블_이름(열_이름) -- 외래 키(FK)
);</code></pre>
<strong>3) 데이터 입력하기: <span style='color:blue'><code>INSERT INTO</code></span></strong><pre><code class="language-sql">INSERT INTO 테이블_이름 VALUES(데이터1, 데이터2, ..., 데이터n);
INSERT INTO 테이블_이름 VALUES(데이터1, 데이터2, ..., 데이터n); </code></pre>
<h3 id="✔️-05-2-제약조건으로-테이블-만들기">✔️ 05-2 제약조건으로 테이블 만들기</h3>
</li>
</ul>
</li>
<li><strong>제약조건</strong>: 데이터의 무결성을 지키기 위해 제한하는 조건<ul>
<li><strong>데이터의 무결성</strong>: 데이터에 결함이 없음<ul>
<li>EX) 네이버 회원의 아이디가 중복되면...? 안됨 ➡️ 결함을 미리 방지하기 위해 회원 테이블의 아이디를 기본 키(PK: 중복되지 않고, 비어 있지도 않음)로 지정</li>
</ul>
</li>
<li><strong>대표적인 제약조건</strong>
기본 키(FK) 제약조건, 외래 키(FK) 제약조건, 고유 키(Unique) 제약조건, 체크(Check) 제약조건, 기본값(Default) 정의, NOT NULL 제약조건 등</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li><strong>기본 키 제약조건</strong>: 테이블을 구분할 수 있는 식별자<ul>
<li>기본 키에 입력되는 값은 중복될 수 없고, <code>NULL</code> 값이 입력될 수 없음<ul>
<li>예) 회원 테이블의 아이디, 학생 테이블의 학생, 직원 테이블의 사번 등</li>
</ul>
</li>
<li>대부분의 테이블은 기본 키를 가져야 함</li>
<li>테이블은 기본 키를 1개만 가질 수 있음</li>
<li><strong>열의 정의 뒤에 <span style='color:blue'><code>PRIMARY KEY</code> 예약어</span> 지정</strong></li>
<li><strong><code>ALTER TABLE</code>에서 기본 키 설정</strong><pre><code class="language-sql">DROP TABLE IF EXISTS 테이블_이름;
CREATE TABLE 테이블_이름
( 열_이름1 데이터형식 NULL(or NOT NULL),
  열_이름2 데이터형식 NULL(or NOT NULL),
  ...
);
ALTER TABLE 테이블_이름
  ADD CONSTRAINT
  PRIMARY KEY (열_이름);</code></pre>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li><strong>외래 키 제약조건</strong>: 두 테이블 사이의 관계를 연결해주고, 그 결과 데이터의 무결성을 보장해주는 역할<ul>
<li><strong>기본 키-외래 키 관계</strong>: 기본 키가 있는 테이블은 <span style='color:red'>기준 테이블</span>, 외래 키가 있는 테이블은 <span style='color:red'>참조 테이블</span></li>
<li>참조 테이블이 참조하는 기준 테이블의 열은 반드시 기본 키나, 고유 키로 설정되어 있어야 함</li>
<li><strong><code>CREATE TABLE</code>에서 외래 키 설정: <span style='color:blue'><code>FOREIGN KEY(열이름) REFERENCES 기준테이블(열이름)</code></span></strong><pre><code class="language-sql">DROP TABLE IF EXISTS 테이블_이름1, 테이블_이름2;
CREATE TABLE 테이블_이름1 -- 기준 테이블
( 열_이름 데이터형식 NULL(or NOT NULL) PRIMARY KEY,
  열_이름2 데이터형식 NULL(or NOT NULL),
  ...
);
CREATE TABLE 테이블_이름2 -- 참조 테이블
( 열_이름1 데이터형식 NULL(or NOT NULL) PRIMARY KEY,
  열_이름 데이터형식 NULL(or NOT NULL),
  ...
  FOREIGN KEY(열_이름) REFERENCES 기준_테이블(열_이름);
);</code></pre>
</li>
<li><strong><code>ALTER TABLE</code>에서 외래 키 설정</strong><pre><code class="language-sql">DROP TABLE IF EXISTS 테이블_이름;
CREATE TABLE 테이블_이름 -- 참조 테이블
( 열_이름1 데이터형식 NULL(or NOT NULL) PRIMARY KEY,
  열_이름 데이터형식 NULL(or NOT NULL),
  ...
);
ALTER TABLE 참조테이블
  ADD CONSTRAINT
  FOREIGN KEY(열_이름)
  REFERENCES 기준_테이블(열_이름);</code></pre>
</li>
<li><strong>기준 테이블의 열이 변결될 경우</strong><ul>
<li>기본 키-외래 키로 맺어진 후에는 기준 테이블의 열 이름이 변경되지 않음(열 이름이 변경되면 참조 테이블의 데이터에 문제 발생)</li>
<li><strong><code>ALTER TABLE</code>에서 <span style='color:blue'><code>ON UPDATE CASCADE</code> 문, <code>ON DELETE CASCADE</code> 문</span> 설정: 기준 테이블의 열 이름이 변경될 때 참조 테이블의 열 이름이 자동으로 변경되도록 하는 기능</strong><pre><code class="language-sql">DROP TABLE IF EXISTS 테이블_이름;
CREATE TABLE 테이블_이름 -- 참조 테이블
( 열_이름1 데이터형식 NULL(or NOT NULL) PRIMARY KEY,
열_이름 데이터형식 NULL(or NOT NULL),
...
);
ALTER TABLE 참조_테이블
ADD CONSTRAINT
FOREIGN KEY(열_이름) REFERENCES 기준_테이블(열_이름)
ON UPDATE CASCADE
ON DELETE CASCADE;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li><p><strong>기타 제약조건(고유 키 제약조건, 체크 제약조건,기본값 정의
,널 값 허용)</strong></p>
</li>
<li><p><strong>1) 고유 키 제약조건</strong></p>
<ul>
<li><strong>고유 키 제약조건</strong>: 중복되지 않는 유일한 값을 입력해야 하는 조건</li>
<li>기본 키 제약조건과 거의 비슷하지만, 고유 키 제약조건은 <code>NULL</code> 값을 허용한다<ul>
<li>예) 회원 테이블 Email 주소</li>
<li><strong>열의 정의 뒤에 <span style='color:blue'><code>NULL</code>, <code>UNIQUE</code></span>로 지정</strong></li>
</ul>
</li>
</ul>
</li>
<li><p><strong>2) 체크 제약조건</strong></p>
<ul>
<li><strong>체크 제약조건</strong>: 입력되는 데이터를 점검하는 기능<ul>
<li>예) 평균 키에 마이너스 값이 입력되지 않게 함: <span style='color:blue'><code>CHECK(height&gt;=100)</code></span></li>
<li><strong>열의 정의 뒤에 <span style='color:blue'><code>CHECK(조건)</code></span> 추가</strong></li>
<li><strong><code>ALTER TABLE</code> 문으로 <span style='color:blue'><code>CHECK(조건)</code></span> 제약조건 추가</strong><pre><code class="language-sql">ALTER TABLE 테이블_이름
ADD CONSTRAINT
CHECK (조건);</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>3) 기본값 정의</strong></p>
<ul>
<li><strong>기본값 정의</strong>: 값을 입력하지 않았을 때 자동으로 입력될 값을 미리 지정해 놓은 방법<ul>
<li>예) 키를 입력하지 않고 기본적으로 160이라고 입력되게 함: <span style='color:blue'><code>DEFAULT 160</code></span></li>
<li><strong>열의 정의 뒤에 <span style='color:blue'><code>DEFAULT &#39;값&#39;</code></span> 추가</strong></li>
<li><strong><code>ALTER TABLE</code> 문으로 <span style='color:blue'><code>DEFAULT &#39;값&#39;</code></span> 제약조건 추가</strong><pre><code class="language-sql">ALTER TABLE 테이블_이름
  ALTER COLUMN 열_이름 SET DEFAULT &#39;값&#39;;</code></pre>
</li>
<li>기본값이 설정된 열에 기본값을 입력하려면 <span style='color:blue'><code>default</code></span>라고 씀<pre><code class="language-sql">INSERT INTO 테이블_이름 VALUES(데이터, 데이터, 데이터, default);</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>4) 널 값 허용</strong></p>
<ul>
<li><strong>널 값 허용</strong>: 널(Null) 값을 허용하려면 생략하거나 <code>NULL</code>을 사용, 허용하지 않으려면 <code>NOT NULL</code>을 사용함<ul>
<li><span style='color:red'><code>NULL</code></span>: 빈 값 허용</li>
<li><span style='color:red'><code>NOT NULL</code></span>: 빈 값을 허용하지 않는다</li>
<li>기본 키(PK)가 설정된 열에는 <code>NULL</code> 값이 있을 수 없음(<code>NOT NULL</code>)</li>
<li><code>NULL</code> 값=아무 것도 없다라는 의미(공백(&#39;&#39;)이나 0과 다름)<h3 id="✔️-05-3-가상의-테이블-뷰view">✔️ 05-3 가상의 테이블: 뷰(View)</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>뷰(View)</strong></p>
<ul>
<li><strong>뷰</strong>: 데이터베이스 개체 중 하나임, 바탕 화면의 바로 가기 아이콘과 비슷<ul>
<li><span style='color:red'>단순 뷰</span>: 하나의 테이블과 연관된 뷰</li>
<li><span style='color:red'>복잡 뷰</span>: 2개 이상의 테이블과 연관된 뷰</li>
</ul>
</li>
<li><strong>뷰의 기본 생성: <span style='color:blue'><code>CREATE VIEW</code></span></strong><pre><code class="language-sql">CREATE VIEW 뷰_이름
AS
  SELECT 문;</code></pre>
</li>
<li><strong>뷰에 접근하는 방식: <span style='color:blue'><code>SELECT</code></span></strong><pre><code class="language-sql">SELECT 열_이름 FROM 뷰_이름
  [WHERE 조건];</code></pre>
</li>
<li><strong>뷰를 사용하는 이유</strong><ol>
<li>보안에 도움이 됨</li>
<li>복잡한 SQL을 단순하게 만들 수 있음</li>
</ol>
</li>
</ul>
</li>
<li><p><strong>뷰의 실제 작동</strong></p>
<ul>
<li><strong>뷰의 실제 생성: <span style='color:blue'>CREATE VIEW</span></strong><ul>
<li><span style='color:blue'>AS 별칭</span> 사용(작은따옴표 또는 큰따옴표로 묶음, 띄어쓰기 가능)</li>
<li>뷰를 조회할 때 열 이름에 공백이 있으면 <span style='color:blue'>백틱(`)</span> 사용<pre><code class="language-sql">USE 데이터베이스_이름;
CREATE VIEW 뷰_이름
AS
SELECT 문;
SELECT DISTINCT `뷰_열이름1`, `뷰_열이름2`, ... FROM 뷰_이름; -- 백틱(`)을 사용</code></pre>
</li>
</ul>
</li>
<li><strong>뷰의 수정: <span style='color:blue'><code>ALTER VIEW</code></span></strong><pre><code class="language-sql">ALTER VIEW 뷰_이름
AS
  SELECT 문;
SELECT DISTINCT `뷰_열이름1`, `뷰_열이름2`, ... FROM 뷰_이름; -- 백틱(`)을 사용</code></pre>
</li>
<li><strong>뷰의 삭제: <span style='color:blue'><code>DROP VIEW</code></span></strong><pre><code class="language-sql">DROP VIEW 뷰_이름;</code></pre>
</li>
<li><strong>뷰의 정보 확인: <span style='color:blue'><code>DESCRIBE</code>, <code>SHOW CREATE VIEW</code></span></strong><pre><code class="language-sql">DESCRIBE 뷰_이름;</code></pre>
<pre><code class="language-sql">SHOW CREATE VIEW 뷰_이름;</code></pre>
</li>
<li><strong>뷰를 통한 데이터의 수정/삭제: <span style='color:blue'><code>UPDATE</code>, <code>DELETE</code></span></strong><pre><code class="language-sql">UPDATE 뷰_이름 SET ... WHERE ...; -- 수정</code></pre>
<pre><code class="language-sql">DELETE FROM 뷰_이름 WHERE...; -- 삭제</code></pre>
</li>
<li><strong>뷰를 통한 데이터의 입력: <span style='color:blue'><code>INSERT</code></span></strong><ul>
<li><span style='color:blue'><code>WITH CHECK OPTION</code> 예약어</span>: 뷰에 설정된 값의 범위가 벗어나는 값은 입력되지 않도록 함<pre><code class="language-sql">INSERT INTO 뷰_이름 VALUES(데이터1,데이터2,...,); -- 수정</code></pre>
<pre><code class="language-sql">ALTER VIEW 뷰_이름
AS
SELECT 문
WITH CHECK OPTION;
INSERT INTO 뷰_이름 VALUES(데이터1,데이터2,...,); -- 수정</code></pre>
</li>
</ul>
</li>
<li><strong>뷰가 참조하는 테이블의 삭제: <span style='color:blue'><code>DROP TABLE</code></span></strong><ul>
<li><span style='color:blue'><code>CHECK TABLE</code> 문</span>으로 뷰의 상태를 확인할 수 있음<pre><code class="language-sql">DROP TABLE IF EXISTS 테이블_이름;</code></pre>
<pre><code class="language-sql">SELECT * FROM 뷰_이름; -- 에러 발생</code></pre>
<pre><code class="language-sql">CHECK TABLE 뷰_이름; -- 뷰의 상태 확인</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고문헌">📌 참고문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p216-p270.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-3]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-3</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-3</guid>
            <pubDate>Sat, 08 Oct 2022 15:47:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-4강-sql-고급-문법">📌 4강 SQL 고급 문법</h2>
<h3 id="✔️-04-1-mysql의-데이터-형식">✔️ 04-1 MySQL의 데이터 형식</h3>
<ul>
<li><p><strong><span style='color:red'>데이터 형식(정수형, 문자형, 실수형, 날짜형)</span></strong></p>
<ul>
<li>각 데이터 형식마다 크기나 표현할 수 있는 숫자의 범위가 다름</li>
</ul>
</li>
<li><p><strong>정수형</strong>: 소수점이 없는 숫자(ex. 인원 수, 가격, 수량 등)
<img src="https://velog.velcdn.com/images/so-kr/post/1c999d49-e147-416f-b3ef-1851eb63c50f/image.png" alt=""></p>
<ul>
<li>1바이트=256개</li>
<li><code>UNSIGNED</code> 예약어: 값의 범위가 0부터 시작됨</li>
</ul>
</li>
<li><p><strong>문자형</strong>: 문자형은 글자를 저장하기 위해 사용함
<img src="https://velog.velcdn.com/images/so-kr/post/3cfdcb60-1b77-418f-ab19-31ff35015397/image.png" alt=""></p>
<ul>
<li>글자의 개수가 고정된 경우: <code>CHAR</code></li>
<li>글자의 개수가 변동될 경우: <code>VARCHAR</code></li>
<li>숫자 의미: 1) 더하기/빼기 등의 연산에 의미, 2) 크다/작다 또는 순서에 의미<ul>
<li>ex. 전화번호: 숫자(정수형)가 아닌 문자형이 더 효과적임</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>대량의 데이터 형식</strong>: 더 큰 데이터를 저장하는 데이터 형식
<img src="https://velog.velcdn.com/images/so-kr/post/22927c20-e0e4-46cf-a763-4c3cbf0c08f0/image.png" alt=""></center></p>
<ul>
<li><code>TEXT</code>: 글자 데이터(대량의 텍스트)</li>
<li><code>BLOB</code>: 글자가 아닌 이미지, 동영상 등의 데이터(대량의 이진 데이터)</li>
</ul>
</li>
<li><p><strong>실수형</strong>: 소수점이 있는 숫자
<img src="https://velog.velcdn.com/images/so-kr/post/9214c5b2-48d2-4163-a510-526766df9d44/image.png" alt=""></p>
<ul>
<li>과학 기술용 데이터가 아닌 이상 <code>FLOAT</code> 사용(ex. 시력)</li>
</ul>
</li>
<li><p><strong>날짜형</strong>: 날짜 및 시간을 저장할 때 사용
<img src="https://velog.velcdn.com/images/so-kr/post/c350d379-c476-479d-8277-0da38c7c6909/image.png" alt=""></p>
</li>
</ul>
<hr>
<ul>
<li><strong><span style='color:red'>변수의 사용</span></strong>: 변수를 선언하고 사용<ul>
<li>변수의 선언과 값의 대입 형식<pre><code class="language-sql">SET @변수이름 = 변수의 값; -- 변수의 선언 및 값 대입
SELECT @변수이름; -- 변수의 값 출력</code></pre>
</li>
<li><code>LIMIT</code>에는 변수를 사용할 수 없음(문법상 오류)</li>
<li>대신, <code>LIMIT</code>에 변수를 사용하기 위해 <code>PREPARE</code>와 <code>EXECUTE</code> 사용<ul>
<li><code>PREPARE</code>는 실행하지 않고 SQL 문만 준비해 놓고</li>
<li><code>EXECUTE</code>에서 실행하는 방식</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li><p><strong><span style='color:red'>데이터 형 변환(명시적인 변환, 암시적인 변환)</span></strong></p>
</li>
<li><p><strong>1) 명시적인 변환</strong></p>
<ul>
<li>데이터 형식을 변환하는 함수: <span style='color:blue'><code>CAST()</code>, <code>CONVERT()</code> 형식</span><pre><code class="language-sql">CAST (값 AS 데이터_형식 [ (길이) ])
CONVERT (값, 데이터_형식 [ (길이) ])</code></pre>
</li>
</ul>
</li>
<li><p><strong>2) 암시적인 변환</strong></p>
<ul>
<li>함수를 사용하지 않고도 자연스럽게 형이 변환되는 것</li>
<li><span style='color:blue'>예시</span><pre><code class="language-sql">SELECT CONCAT(100, &#39;200&#39;); -- output: 100200 (숫자 100이 문자로 자동 변환)
SELECT 100 + &#39;200&#39;; -- output: 300 (문자 &#39;200&#39;이 숫자로 자동 변환)</code></pre>
<h3 id="✔️-04-2-조인-두-테이블을-묶는-방법⭐⭐⭐">✔️ 04-2 조인: 두 테이블을 묶는 방법⭐⭐⭐</h3>
</li>
</ul>
</li>
<li><p><strong>조인</strong>: 두 개의 테이블을 서로 묶어서 하나의 결과를 만들어 내는 것</p>
</li>
<li><p><strong>내부 조인</strong>: 두 테이블에 모두 데이터가 있어야만 결과가 나옴</p>
<ul>
<li><p><span style='color:red'>일대다(one to many) 관계</span>: 주로 기본 키(PK)와 외래 키(FK) 관계(PK-FK 관계)</p>
<ul>
<li><span style='color:blue'>예시)</span> 회원 테이블의 아이디(기본 키, PK)-구매 테이블의 아이디(외래 키, FK)</li>
<li><span style='color:blue'>예시)</span> 회사원 테이블의 회사원(PK)과 급여 테이블의 회사원(FK), 학생 테이블의 학생(PK)과 학점 테이블의 학생(FK)</li>
<li>두 테이블의 조인을 위해서는 기본 키-외래 키 관계를 맺어져야 함(일대다 관계)</li>
</ul>
</li>
<li><p>내부 조인 형식(<code>INNER JOIN</code>=<code>JOIN</code>)</p>
<ul>
<li><span style='color:red'>내부 조인은 두 테이블에 모두 있는 내용만 조인되는 방식임</span><pre><code class="language-sql">SELECT &lt;열 목록&gt;
FROM &lt;첫 번째 테이블&gt; 별칭
    INNER JOIN &lt;두 번째 테이블&gt; 별칭 -- 혹은 JOIN &lt;두 번째 테이블&gt;
    ON &lt;조인될 조건&gt;
[WHERE 검색 조건];</code></pre>
<ul>
<li>동일한 열 이름이 존재한다면 <span style='color:blue'><code>테이블이름.열이름</code></span> 형식으로 표기</li>
<li><code>FROM</code> 절에 나오는 테이블의 이름 뒤에 <span style='color:blue'>별칭(alias)</span>을 줄 수 있음</li>
<li>만약, 테이블 양쪽 중에 한곳이라도 내용이 있을 때 조인하려면 <span style='color:red'>외부 조인</span>을 사용해야 함</li>
<li>중복된 결과 1개만 출력하기: <span style='color:blue'><code>DISTINCT</code> 문</span> 활용</li>
</ul>
</li>
<li><span style='color:blue'>예시)</span> 사이트에 한 번이라도 구매한 기록이 있는 회원만 출력하기(구매 테이블(buy)과 회원 테이블(member) 사용)<pre><code class="language-sql">SELECT DISTINCT M.mem_id, M.mem_name, M.addr
  FROM buy B
    INNER JOIN member M
    ON B.mem_id = M.mem_id
  ORDER BY M.mem_id;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>외부 조인</strong>: 한쪽에만 데이터가 있어도 결과가 나옴</p>
<ul>
<li>외부 조인 형식(<code>OUTER JOIN</code>)</li>
<li><span style='color:red'>외부 조인은 두 테이블을 조인할 때 필요한 내용이 한쪽 테이블에만 있어도 결과를 추출할 수 있음</span><pre><code class="language-sql">SELECT &lt;열 목록&gt;
FROM &lt;첫 번째 테이블(LEFT 테이블)&gt; 별칭
    &lt;LEFT|RIGHT|FULL&gt; OUTER JOIN &lt;두 번째 테이블(RIGHT 테이블)&gt; 별칭
    ON &lt;조인될 조건&gt;
[WHERE 검색 조건];</code></pre>
<ul>
<li><span style='color:blue'><code>LEFT OUTER JOIN</code> 문</span>: 왼쪽 테이블의 내용은 모두 출력되어야 한다(왼쪽에 있는 테이블을 기준으로 외부 조인)</li>
<li><span style='color:blue'><code>RIGHT OUTER JOIN</code> 문</span>: 오른쪽 테이블의 내용은 모두 출력되어야 한다(오른쪽에 있는 테이블을 기준으로 외부 조인)</li>
<li><span style='color:blue'><code>FULL OUTER JOIN</code> 문</span>: 왼쪽 외부 조인과 오른쪽 외부 조인이 합쳐진 것으로 왼쪽이든 오른쪽이든 한쪽에 들어 있는 내용이면 출력함</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>기타 조인(상호 조인, 자체 조인)</strong></p>
</li>
<li><p><strong>1) 상호 조인(<code>CROSS JOIN</code>)</strong>: 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시키는 기능<span style='color:blue'>(=카티션 곱)</span></p>
<ul>
<li><span style='color:blue'>상호 조인 형식</span><pre><code class="language-sql">SELECT &lt;열 목록&gt;
FROM &lt;첫 번째 테이블&gt;
    CROSS JOIN &lt;두 번째 테이블&gt;;</code></pre>
</li>
<li><span style='color:blue'>특징</span>: 1. <code>ON</code> 구문을 사용할 수 없음, 2. 결과의 내용은 의미가 없음(랜덤 조인), 3. 상호 조인의 주 용도는 테스트하기 위해 대용량의 데이터를 생성할 때</li>
<li>대용량의 테이블 만들기: <span style='color:blue'><code>CREATE TABLE ~ SELECT</code> 문</span><pre><code class="language-sql">CREATE TABLE &lt;테이블_이름&gt;
  SELECT &lt;열 목록&gt;
    FROM &lt;첫 번째 테이블&gt;
      CROSS JOIN &lt;두 번째 테이블&gt;;</code></pre>
</li>
</ul>
</li>
<li><p><strong>2) 자체 조인</strong>: 자신이 자신과 조인한다(1개의 테이블을 사용함)</p>
<ul>
<li><span style='color:blue'>자체 조인 형식</span><pre><code class="language-sql">SELECT &lt;열 목록&gt;
FROM &lt;테이블&gt; 별칭A
    JOIN &lt;테이블&gt; 별칭B;
    ON &lt;조인될 조건&gt;
[WHERE 검색 조건];</code></pre>
</li>
<li><span style='color:blue'>특징</span>: 하나의 테이블에 같은 테이터가 있지만 2개 이상의 열로 존재할 때 자체 조인 가능함</li>
</ul>
</li>
</ul>
<h3 id="✔️-04-3-sql-프로그래밍">✔️ 04-3 SQL 프로그래밍</h3>
<ul>
<li><strong>스토어드 프로시저</strong>: MySQL에서 프로그래밍 기능이 필요할 때 사용하는 데이터베이스 개체<ul>
<li><em>스토어드 프로시저 구조</em>
```sql
DELIMITER $$ -- 스토어드 프로시저의 코딩
CREATE PROCEDURE 스토어드_프로시저_이름()
BEGIN<pre><code>이 부분에 SQL 프로그래밍 코딩</code></pre>END $$ -- 스토어드 프로시저 종료
DELIMITER ; -- 종료 문자를 다시 세미콜론(;)으로 변경
CALL 스토어드_프로시저_이름(); -- 스토어드 프로시저 실행</li>
</ul>
</li>
<li><strong>변수</strong>는 <span style='color:blue'><code>DECLARE</code></span>로 선언, <span style='color:blue'><code>SET</code></span>으로 값을 대입</li>
</ul>
<hr>
<ul>
<li><strong><code>IF</code> 문</strong>: 조건식이 참이라면 &#39;SQL 문장들&#39; 실행하고 거짓이면 그냥 넘어감<ul>
<li><code>IF</code> 문은 조건식이 참이면 실행</li>
<li><em><code>IF</code> 문 기본 형식</em><ul>
<li>&#39;SQL 문장들&#39;이 한 문장이라면 그 문장만 써도 되지만 두 문장 이상 처리되어야 할 때는 <span style='color:blue'><code>BEGIN ~ END</code></span><pre><code class="language-sql">IF &lt;조건식&gt; THEN
  SQL 문장들
END IF;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><strong><code>IF ~ ELSE</code> 문</strong>: 조건에 따라 다른 부분을 수행할 때<ul>
<li><code>IF ~ ELSE</code> 문은 조건식이 참일 때와 거짓일 때 다른 부분이 실행</li>
<li><em><code>IF ~ ELSE</code> 문 기본 형식</em><pre><code class="language-sql">IF &lt;조건식&gt; THEN
    SQL 문장들1
ELSE
    SQL 문장들2
END IF;</code></pre>
</li>
</ul>
</li>
<li><strong>날짜 관련 함수</strong><ul>
<li><span style='color:blue'><code>CURRENT_DATE()</code></span>: 오늘 날짜를 알려줌</li>
<li><span style='color:blue'><code>CURRENT_TIMESTAMP()</code></span>: 오늘 날짜 및 시간을 함께 알려줌</li>
<li><span style='color:blue'><code>DATEDIFF(날짜1, 날짜2)</code></span>: 날짜2부터 날짜1까지 일수로 몇일인지 알려줌</li>
</ul>
</li>
<li><strong><code>CASE</code> 문</strong>: 여러 가지 조건 중에서 선택해야 하는 경우<ul>
<li><code>CASE</code> 문은 다중 분기로, 여러 조건에 따라 다른 SQL을 실행시킬 수 있음</li>
<li><em><code>CASE</code> 문 기본 형식</em><pre><code class="language-sql">CASE
  WHEN 조건1 THEN
    SQL 문장들1
  WHEN 조건2 THEN
    SQL 문장들2
  WHEN 조건3 THEN
    SQL 문장들3
  ELSE
    SQL 문장들4
END CASE;</code></pre>
</li>
</ul>
</li>
<li><strong><code>WHILE</code> 문</strong>: 필요한 만큼 계속 같은 내용을 반복<ul>
<li><code>WHILE</code> 문은 조건식이 참인 동안에 계속 반복함</li>
<li><em><code>WHILE</code> 문 기본 형식</em><pre><code class="language-sql">WHILE &lt;조건식&gt; DO
    SQL 문장들
END WHILE;</code></pre>
</li>
<li><span style='color:blue'><code>ITERATE [레이블]</code></span>: 지정한 레이블로 가서 계속 진행함 = 프로그래밍 언어의 CONTINUE 문(반복문을 계속 진행)</li>
<li><span style='color:blue'><code>LEAVE [레이블]</code></span>: 지정한 레이블을 빠져나감(즉, WHILE 문이 종료됨) = 프로그래밍 언어의 BREAK 문(반복문을 빠져 나감)</li>
</ul>
</li>
<li><strong>동적 SQL</strong>: 미리 SQL을 준비한 후에 나중에 실행하는 것<ul>
<li><span style='color:blue'><code>PREPARE</code>와 <code>EXECUTE</code> 문</span><ul>
<li><code>PREPARE</code>: SQL 문을 실행하지는 않고 미리 준비만 해놓고</li>
<li><code>EXECUTE</code>: 준비한 SQL 문을 실행</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고문헌">📌 참고문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p158-p212.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-2]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-2</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-2</guid>
            <pubDate>Fri, 07 Oct 2022 17:20:23 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-3강-sql-기본-문법">📌 3강 SQL 기본 문법</h2>
<h3 id="✔️-03-1-selectfromwhere">✔️ 03-1 SELECT<del>FROM</del>WHERE</h3>
<ul>
<li>실습용 데이터베이스 구축하기
1) 데이터베이스 만들기: <strong><code>DROP</code>문, <code>CREATE</code>문</strong><pre><code class="language-sql">DROP DATABASE IF EXISTS 데이터베이스_이름; -- 기존 데이터베이스 삭제
CREATE DATABASE 데이터베이스_이름; -- 데이터베이스 새로 만들기</code></pre>
2) 테이블 만들기: <strong><code>USE</code>문, <code>CREATE</code>문</strong><pre><code class="language-sql">USE 데이터베이스_이름; -- 데이터베이스 선택
CREATE TABLE 테이블_이름
( 열_이름 데이터타입 PK NN ...
  열_이름 데이터타입 PK NN ...
);</code></pre>
3) 데이터 입력하기: <strong><code>INSERT</code>문</strong><pre><code class="language-sql">INSERT INTO 테이블_이름 VALUES(데이터, 데이터, ..., 데이터);</code></pre>
4) 데이터 조회하기: <strong><code>SELECT</code>문</strong><pre><code class="language-sql">SELECT 열_이름 FROM 테이블_이름</code></pre>
</li>
<li><strong><code>USE</code> 문</strong><ul>
<li>데이터베이스를 지정 또는 변경하는 형식, 한 번 지정하면 계속 유지됨: <span style="color:blue"><code>USE</code> 문</span><pre><code class="language-sql">USE 데이터베이스_이름;</code></pre>
</li>
</ul>
</li>
<li><strong><code>SELECT</code> 문</strong><ul>
<li>테이블을 조회하는 형식: <span style="color:blue"><code>SELECT</code> 문</span><pre><code class="language-sql">SELECT 열_이름
    FROM 테이블_이름
    WHERE 조건식
    GROUP BY 열_이름
    HAVING 조건식
    ORDER BY 열_이름
    LIMIT 숫자</code></pre>
</li>
</ul>
</li>
<li><strong><code>SELECT ~ FROM ~ WHERE</code></strong><ul>
<li>기본 형식: <strong>SELECT</strong> 열이름 ~ <strong>FROM</strong> 테이블이름 ~ <strong>WHERE</strong> 조건식<pre><code class="language-sql">SELECT 열_이름 FROM 테이블_이름 WHERE 조건식</code></pre>
<pre><code class="language-sql">SELECT 열_이름
    FROM 테이블_이름
    WHERE 조건식</code></pre>
</li>
<li><span style="color:blue">예시</span>: 데이터베이스(market_db)를 선택하고 회원 테이블(member)을 조회하기<ul>
<li>*: 모든 열을 지정할 때 사용하는 기호<pre><code class="language-sql">USE market_db;
SELECT * FROM member; -- *는 모든 것을 의미(즉, 모든 열), FROM 테이블_이름
SELECT * FROM market_db.member; -- FROM 데이터베이스_이름.테이블_이름(위 코드와 동일한 결과)</code></pre>
</li>
</ul>
</li>
<li><span style="color:blue">예시</span>: 회원 테이블(member)에서 여러 개의 열(addr, debut_date, mem_name) 조회하기<pre><code class="language-sql">SELECT addr 주소, debut_date &quot;데뷔 일자&quot;, mem_name 
    FROM member; -- addr 열 이름은 주소, debut_date 열 이름은 데뷔 일자로 지정됨</code></pre>
<ul>
<li><strong>열 이름 별칭(alias) 지정</strong>: SELECT 문에서 실제 열 이름 대신에 출력되도록 설정하는 방식<ul>
<li>열 이름 다음에 지정하고 싶은 별칭 입력(단, 공백이 있는 별칭은 큰따옴표(&quot;&quot;)로 묶어줌)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>관계 연산자</strong><ul>
<li>두 연산자의 값이 같은지: <span style="color:blue"><code>=</code></span></li>
<li>두 연산자의 값이 서로 큰지 작은지: <span style="color:blue"><code>&gt;</code>, <code>&lt;</code></span></li>
<li>두 연산자의 값이 서로 크거나 같은지, 작거나 같은지: <span style="color:blue"><code>&gt;=</code>, <code>&lt;=</code></span></li>
<li><span style="color:blue">관계 연산자 예시</span>: 회원 테이블(member)에서 인원(mem_number)이 4명인 회원의 모든 열 조회하기<pre><code class="language-sql">SELECT * FROM member WHERE mem_number = 4;</code></pre>
</li>
</ul>
</li>
<li><strong>논리 연산자</strong>: 관계 연산자가 2개 이상 나오면 <code>AND</code>, <code>OR</code> 등으로 참, 거짓을 판별함<ul>
<li>논리식이 모두 참이면 참: <span style="color:blue"><code>AND</code></span></li>
<li>논리식 중 하나라도 참이면 참: <span style="color:blue"><code>OR</code></span></li>
<li><span style="color:blue">논리 연산자 예시</span>: 회원 테이블(member)에서 평균 키(height)가 165이상이면서 인원(mem_number)도 6명 초과인 회원의 여러 개의 열(mem_name, height, mem_number) 조회하기<pre><code class="language-sql">SELECT mem_name, height, mem_number
    FROM member
    WHERE height &gt;= 165 AND mem_number &gt; 4;</code></pre>
</li>
</ul>
</li>
<li><strong><code>BETWEEN ~ AND</code></strong><ul>
<li>범위에 있는 값을 구하는 경우: <span style="color:blue"><code>BETWEEN ~ AND</code></span></li>
<li><span style="color:blue"><code>BETWEEN ~ AND</code> 예시</span>: 회원 테이블(member)에서 평균 키(height)가 163이상 165이하인 회원의 두 개의 열(mem_name, height) 조회하기<pre><code class="language-sql">SELECT mem_name, height
    FROM member
    WHERE height BETWEEN 163 AND 165;</code></pre>
</li>
</ul>
</li>
<li><strong><code>IN()</code></strong><ul>
<li>여러 문자 중 하나에 포함되는지 비교하는 경우: <span style="color:blue"><code>IN()</code></span></li>
<li><span style="color:blue"><code>IN()</code> 예시</span>: 회원 테이블(member)에서 주소(addr)가 경기/전남/경남 중 한 곳에 사는 회원의 두 개의 열(mem_name, addr) 조회하기<pre><code class="language-sql">SELECT mem_name, addr
    FROM member
    WHERE addr IN(&#39;경기&#39;, &#39;전남&#39;, &#39;경남&#39;);</code></pre>
</li>
</ul>
</li>
<li><strong><code>LIKE</code></strong><ul>
<li>문자열의 일부 글자를 검색하는 경우: <span style="color:blue"><code>LIKE</code></span><ul>
<li><code>%</code> : 문자열에서 여러 문자에 대응하는 기호</li>
<li><code>_</code> : 문자열에서 한 문자에 대응하는 기호</li>
</ul>
</li>
<li><span style="color:blue"><code>LIKE</code> 예시</span>: 회원 테이블(member)에서 이름(mem_name)의 첫 글자가 &#39;우&#39;로 시작하는 회원의 모든 열 조회하기<pre><code class="language-sql">SELECT *
    FROM member
    WHERE mem_name LIKE &#39;우%&#39;; -- %는 그 뒤에 무엇이든 허용한다는 의미</code></pre>
</li>
<li><span style="color:blue"><code>LIKE</code> 예시</span>: 회원 테이블(member)에서 이름(mem_name)의 앞 두 글자는 상관없고 뒤는 &#39;핑크&#39;인 회원의 모든 열 조회하기<pre><code class="language-sql">SELECT *
    FROM member
    WHERE mem_name LIKE &#39;__핑크&#39;; -- 언더바(-)는 한 글자와 매치</code></pre>
</li>
</ul>
</li>
<li><strong>서브 쿼리</strong><ul>
<li>SELECT 안에 또 다른 SELECT: <span style="color:blue">서브 쿼리, 하위 쿼리</span></li>
<li><span style="color:blue">서브 쿼리 예시</span>: 회원 테이블(member)에서 에이핑크의 평균 키인 164보다 평균 키가 큰 회원의 두 개의 열(mem_name, height) 조회하기<pre><code class="language-sql">SELECT mem_name, height FROM member
    WHERE height &gt; (SELECT height FROM member WHERE mem_name = &#39;에이핑크&#39;);</code></pre>
<h3 id="✔️-03-2-select-문order-by-절-group-by-절">✔️ 03-2 SELECT 문(ORDER BY 절, GROUP BY 절)</h3>
</li>
</ul>
</li>
<li><strong><code>ORDER BY</code> 절</strong><ul>
<li>결과가 출력되는 순서를 지정하기(결과의 값이나 개수에 대한 영향 없음): <span style="color:blue"><code>ORDER BY</code> 절</span><ul>
<li><span style="color:blue"><code>ASC</code></span>(기본값) : 오름차순</li>
<li><span style="color:blue"><code>DESC</code></span> : 내림차순</li>
</ul>
</li>
<li><span style="color:blue"><code>ORDER BY</code> 절 예시(ASC)</span>: 회원 테이블(member)에서 데뷔 일자(debut_date)가 빠른 순서대로 정렬하여 세 개의 열(mem_id, mem_name, debut_date) 조회하기<pre><code class="language-sql">SELECT mem_id, mem_name, debut_date
    FROM member
    ORDER BY debut_date;</code></pre>
</li>
<li><span style="color:blue"><code>ORDER BY</code> 절 예시(DESC)</span>: 회원 테이블(member)에서 데뷔 일자(debut_date)가 늦은 순서대로 정렬하여 세 개의 열(mem_id, mem_name, debut_date) 조회하기<pre><code class="language-sql">SELECT mem_id, mem_name, debut_date
    FROM member
    ORDER BY debut_date DESC;</code></pre>
</li>
</ul>
</li>
<li><strong><code>LIMIT</code></strong><ul>
<li>출력하는 개수를 제한하기: <span style="color:blue"><code>LIMIT</code></span></li>
<li><span style="color:blue"><code>LIMIT</code> 예시</span>: 회원 테이블(member)에서 모든 열을 조회할 때 전체 중 앞에서 3건만 조회하기<pre><code class="language-sql">SELECT *
    FROM member
    LIMIT 3;</code></pre>
</li>
<li><span style="color:blue"><code>LIMIT 시작, 개수</code></span>(=LIMIT 개수 OFFSET 시작)<ul>
<li>LIMIT 0, 3: 0번째부터 3건이라는 의미</li>
</ul>
</li>
<li><span style="color:blue"><code>LIMIT 시작, 개수</code> 예시</span>: 회원 테이블(member)에서 모든 열을 조회할 때 전체 중 0번째부터 3건만 조회하기<pre><code class="language-sql">SELECT *
    FROM member
    LIMIT 0, 3; -- LIMIT 3 OFFSET 0</code></pre>
</li>
</ul>
</li>
<li><strong><code>DISTINCT</code></strong><ul>
<li>중복된 결과를 제거하여 출력하기(조회된 결과에서 중복된 데이터를 1개만 남김): <span style="color:blue"><code>DISTINCT</code></span></li>
<li><span style="color:blue"><code>DISTINCT</code> 예시</span>: 회원 테이블(member)에서 회원이 사는 지역(addr)을 조회할 때 중복을 제거하여 조회하기<pre><code class="language-sql">SELECT DISTINCT addr FROM member;</code></pre>
</li>
</ul>
</li>
<li><strong><code>GROUP BY</code> 절</strong><ul>
<li>데이터를 그룹화해주는 기능(그룹을 묶어주는 역할): <span style="color:blue"><code>GROUP BY</code> 절</span></li>
<li><span style="color:blue"><code>GROUP BY</code> 절 예시</span>: 구매 테이블(buy)에서 회원(mem_id)이 구매한 개수(amount)의 총합 출력하기<pre><code class="language-sql">SELECT mem_id &quot;회원 아이디&quot;, SUM(amount) &quot;총 구매 개수&quot;
    FROM buy GROUP BY mem_id;</code></pre>
</li>
</ul>
</li>
<li><strong>집계함수</strong>
<img src="https://velog.velcdn.com/images/so-kr/post/ccff4c9c-9233-45b5-9978-2848bbf58596/image.png" alt=""><ul>
<li><code>COUNT(*)</code> : 모든 행의 개수를 셈</li>
<li><code>COUNT(열_이름)</code> : 열 이름의 값이 NULL인 것을 제외한 행의 개수를 셈</li>
</ul>
</li>
<li><strong><code>HAVING</code> 절</strong><ul>
<li>집계 함수에 대해서 조건을 제한하는 것(GROUP BY 절 다음에 HAVING 절이 나와야 함): <span style="color:blue"><code>HAVING</code> 절</span></li>
<li><span style="color:blue"><code>HAVING</code> 절 예시</span>: 구매 테이블(buy)에서 회원(mem_id)이 구매한 금액(price*amount)의 총합에서 총 구매액이 1000이상인 회원 아이디 출력하기<pre><code class="language-sql">SELECT mem_id &quot;회원 아이디&quot;, SUM(price*amount) &quot;총 구매 금액&quot;
    FROM buy
    GROUP BY mem_id
    HAVING SUM(price*amount) &gt; 1000;</code></pre>
<h3 id="✔️-03-3-데이터-변경하기">✔️ 03-3 데이터 변경하기</h3>
</li>
</ul>
</li>
<li><strong><code>INSERT</code> 문</strong><ul>
<li>테이블에 데이터를 삽입하는 명령어: <span style="color:blue"><code>INSERT</code> 문</span><pre><code class="language-sql">INSERT INTO 테이블_이름 [(열1, 열2, ...)] VALUES (값1, 값2, ...);</code></pre>
</li>
<li>열 이름을 생략할 경우: VALUES 다음에 나오는 값들의 순서 및 개수는 테이블을 정의할 때의 열 순서 및 개수와 동일해야 함!</li>
</ul>
</li>
<li><strong><code>AUTO_INCREMENT</code></strong><ul>
<li>열을 정의할 때 1부터 증가하는 값을 입력해 줌: <span style="color:blue"><code>AUTO_INCREMENT</code></span><ul>
<li><span style="color:red">단, <code>AUTO_INCREMENT</code>로 지정하는 열은 꼭 <code>PRIMARY KEY</code>로 지정해야 함</span></li>
</ul>
</li>
<li><code>AUTO_INCREMENT</code>의 시작값과 증가값 지정<pre><code class="language-sql">ALTER TABLE 테이블_이름 AUTO_INCREMENT=시작값; -- 시작값 지정
SET @@auto_increment_increment=증가값; -- 증가값 지정</code></pre>
</li>
<li><span style="color:blue"><code>AUTO_INCREMENT</code> 예시</span>: 아이디(toy_id) 열이 자동 증가인 테이블 만들기(시작값: 1000, 증가값: 3이면 아이디는 1000, 1003, 1006, ..으로 증가함)<pre><code class="language-sql">CREATE TABLE hongong(
    toy_id INT AUTO_INCREMENT PRIMARY KEY,
    toy_name CHAR(4),
    age INT);
ALTER TABLE hongong AUTO_INCREMENT=1000; -- 시작값은 1000으로 지정
SET @@auto_increment_increment=3; -- 증가값은 3으로 지정</code></pre>
</li>
</ul>
</li>
<li><strong><code>INSERT INTO ~ SELECT</code> 구문</strong><ul>
<li>다른 테이블의 데이터를 가져와서 한 번에 대량으로 입력하는 경우: <span style="color:blue"><code>INSERT INTO ~ SELECT</code> 구문</span><pre><code class="language-sql">INSERT INTO 테이블_이름 (열_이름1, 열_이름2,...)
    SELECT 문;</code></pre>
</li>
</ul>
</li>
<li><strong><code>UPDATE</code> 문</strong><ul>
<li>테이블에 데이터를 수정하는 명령어: <span style="color:blue"><code>UPDATE</code> 문</span><pre><code class="language-sql">UPDATE 테이블_이름
    SET 열1=값1, 열2=값2,...
    WHERE 조건;</code></pre>
</li>
</ul>
</li>
<li><strong><code>DELETE</code> 문</strong><ul>
<li>테이블에 데이터를 삭제하는 명령어: <span style="color:blue"><code>DELETE</code> 문</span><ul>
<li>행 단위로 삭제(행 데이터 삭제)<pre><code class="language-sql">DELETE FROM 테이블_이름 WHERE 조건;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>대용량 테이블의 삭제</strong><ul>
<li><span style="color:blue"><code>DELETE</code> 문, <code>DROP</code> 문, <code>TRUNCATE</code> 문</span><ul>
<li>DROP 문은 테이블 아예 없어짐, DELETE 문과 TRUNCATE 문은 빈 테이블을 남김</li>
<li>대량의 행 데이터를 모두 삭제할 때는 DELETE 문보다 TRUNCATE 문이 효율적!<pre><code class="language-sql">DELETE FROM 테이블_이름;
DROP TABLE 테이블_이름;
TRUNCATE TABLE 테이블_이름;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고-문헌">📌 참고 문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p102-p154.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MySQL 요약 노트-1]]></title>
            <link>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-1</link>
            <guid>https://velog.io/@so-kr/MySQL-%EC%9A%94%EC%95%BD-%EB%85%B8%ED%8A%B8-1</guid>
            <pubDate>Wed, 05 Oct 2022 07:46:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>MySQL</code> 요약 노트 (2022년 1월 ~ 2022년 3월까지 공부했던 내용 정리)
혼자 공부하는 SQL책과 한빛미디어에서 제공하는 <a href="https://www.youtube.com/watch?v=0cRhit1EJM0&amp;list=PLVsNizTWUw7GCfy5RH27cQL5MeKYnl8Pm">유튜브 강의</a>로 공부함</p>
</blockquote>
<h2 id="📌-1강-데이터베이스와-sql">📌 1강 데이터베이스와 SQL</h2>
<h3 id="✔️-01-1-데이터베이스란">✔️ 01-1 데이터베이스란?</h3>
<ul>
<li><p><strong>데이터베이스</strong>: 데이터의 집합(ex. 카카오톡 메시지, 인스타그램 업로드 사진, 교통카드 이용내역 등)</p>
</li>
<li><p><strong>DBMS</strong>: 데이터베이스를 관리하고 운영하는 소프트웨어</p>
<ul>
<li><strong>ex. 은행 DBMS</strong>: 예금 데이터베이스, 대출 데이터베이스 등 (예금주, 은행직원, 인터넷 뱅킹, ATM 기기 등 동시 접속 및 데이터 공유 O)</li>
<li><strong>cf. 엑셀(Excel)은 DBMS가 아님</strong> (대용량 데이터 관리 X, 여러 사용자와 공유 X)</li>
<li><strong>DBMS의 종류</strong>: MySQL, 오라클(Oracle), SQL 서버(SQL Server), MariaDB 등</li>
<li><strong>DBMS의 분류</strong>: 계층형, 망형, 관계형, 객체지향형, 객체관계형 등<ul>
<li><span style='color:red'>계층형 DBMS</span>: 각 계층이 트리 형태</li>
<li><span style='color:red'>망형 DBMS</span>: 계층형 DBMS의 문제점 개선, 하위에 구성원도 연결된 유연한 구조</li>
<li><strong><span style='color:red'>관계형 DBMS(=RDBMS)</span></strong>: 데이터베이스는 테이블로 구성<ul>
<li><strong>테이블(table)</strong>: 하나 이상의 열(=세로, column)과 행(=가로, row)으로 이루어짐(2차원 구조)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>SQL</strong>: 관계형 데이터베이스(RDBMS)에서 사용되는 언어, &#39;에스큐엘&#39; or &#39;시퀄&#39;</p>
<ul>
<li><strong>표준 SQL</strong>: 국제표준화기구에서 SQL에 대한 표준을 정하고 발표함<h3 id="✔️-01-2-mysql-설치하기">✔️ 01-2 MySQL 설치하기</h3>
</li>
</ul>
</li>
<li><p><strong>MySQL</strong>: 오라클 사에서 제공하는 데이터베이스 관리 소프트웨어(관계형 DBMS)</p>
<ul>
<li><span style='color:red'>무료 에디션</span>: 교육용 or 개인용(ex. 커뮤니티 에디션)</li>
<li><span style='color:red'>상용 에디션</span>: 영리 목적은 비용 지불(ex. Standard, Enterprise, Cluster CGE)</li>
</ul>
</li>
<li><p><strong>MySQL 서버</strong>: MySQL의 여러 소프트웨어 중 엔진 기능을 하는 핵심 소프트웨어(DBMS)</p>
</li>
<li><p><strong>MySQL 워크벤치</strong>: MySQL 서버/연결하기 위한 클라이언트 도구로 SQL 문을 입력하고 실행함</p>
</li>
<li><p><strong>MySQL</strong> vs. <strong>MariaDB</strong>
<img src="https://velog.velcdn.com/images/so-kr/post/981eba82-2871-4c74-90f5-376c7e599a23/image.png" alt=""></p>
</li>
<li><p>💻 <span style="color:blue">MacBook Pro(M1)에 설치하기</span></p>
</li>
</ul>
<hr>
<h2 id="📌-2강-실전용-sql-미리-맛보기">📌 2강 실전용 SQL 미리 맛보기</h2>
<h3 id="✔️-02-1-데이터베이스-모델링">✔️ 02-1 데이터베이스 모델링</h3>
<ul>
<li><p><strong>프로젝트</strong>: 현실 세계에서 일어나는 업무를 컴퓨터 시스템으로 옮겨놓은 과정(=<U>대규모 소프트웨어를 작성하기 위한 전체 과정</U>)</p>
</li>
<li><p><strong>폭포수 모델</strong>: 소프트웨어 개발 단계
1) 프로젝트 계획
2) 업무 분석
3) 시스템 설계
4) 프로그램 구현
5) 테스트
6) 유지보수</p>
</li>
<li><p><strong>데이터베이스 모델링</strong>: 테이블의 구조를 미리 설계하는 개념</p>
<ul>
<li>현실 세상에서 사용되는 사물이나 작업을 DBMS의 데이터베이스 개체로 옮기기 위한 과정<ul>
<li>i.e. 현실에서 쓰이는 것을 테이블로 변경하기 위한 작업</li>
</ul>
</li>
<li>데이터베이스 모델링은 <U>폭포수 모델의 업무 분석과 시스템 설계 단계</U></li>
<li>ex. 인터넷 쇼핑몰의 데이터베이스 모델링 ➡️ 데이터베이스(회원 테이블, 직원 테이블, 구매 테이블, 물품 테이블)</li>
</ul>
</li>
<li><p><strong>전체 데이터베이스 구성도</strong></p>
<ul>
<li><strong>데이터</strong>: 단편적인 정보(개별적인 정보)</li>
<li><strong>테이블</strong>: 표 형태로 표현한 것</li>
<li><strong>데이터베이스</strong>: 테이블이 저장되는 저장소(ex. 쇼핑몰 데이터베이스)</li>
<li><strong>DBMS</strong>: 데이터베이스 관리 시스템 or 소프트웨어(ex. MySQL)</li>
<li><strong>열(column,컬럼,필드)</strong>: 테이블의 세로, 각 테이블은 여러 개의 열로 구성</li>
<li><strong>열 이름</strong>: 각 열을 구분하기 위한 이름, 각 테이블 내에서는 서로 다른 열 이름</li>
<li><strong>데이터 형식</strong>: 열에 저장될 데이터의 형식, 문자 형식, 숫자 형식 등 지정</li>
<li><strong>행(row,로우,레코드)</strong>: 실질적인 진짜 데이터, <U>행 데이터=하나의 행</U><ul>
<li>행의 개수=데이터의 개수</li>
</ul>
</li>
<li><strong>기본 키(Primary Key, PK)</strong>: 기본 키(또는 주키) 열은 각 행을 구분하는 유일한 열(ex. 네이버의 회원 아이디, 학번, 주민등록번호 등)<ul>
<li><span style="color:red">중복 불가능, 빈 데이터 불가능</span></li>
</ul>
</li>
<li><strong>SQL</strong>: DBMS가 알아듣는 언어인 SQL(구조화된 질의 언어)<ul>
<li>i.e. 사람과 DBMS가 소통하기 위한 언어<h3 id="✔️-02-2-데이터베이스-시작부터-끝까지">✔️ 02-2 데이터베이스 시작부터 끝까지</h3>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>데이터베이스 구축 절차</strong></p>
<ul>
<li>데이터베이스 만들기 ➡️ 테이블 만들기 ➡️ 데이터 입력/수정/삭제하기 ➡️ 데이터 조회/활용하기</li>
</ul>
</li>
</ul>
<h3 id="✔️-02-3-데이터베이스-개체">✔️ 02-3 데이터베이스 개체</h3>
<ul>
<li><p><strong>데이터베이스 개체</strong>는 <U>인덱스, 뷰, 스토어드 프로시저, 트리거, 스토어드 함수, 커서 등</U></p>
</li>
<li><p><strong>인덱스(index)</strong>: 책 뒤의 &#39;찾아보기&#39;와 비슷한 개념</p>
<ul>
<li><p>인덱스는 수천만~수억 건 이상의 데이터를 처리할 때 해당 페이지로 이동할 수 있는 효율적인 방법</p>
</li>
<li><p><span style="color:red">ex. 회원 테이블에서 &#39;아이유&#39;를 찾을 때(<strong>인덱스X</strong>)</span></p>
<ul>
<li><code>Execution Plan(실행 계획)</code>탭 클릭: Full Table Scan(전체 테이블 검색)<pre><code class="language-sql">SELECT * FROM member WHERE member_name=&#39;아이유&#39;;</code></pre>
</li>
</ul>
</li>
<li><p><span style="color:red">ex. 회원 테이블에 인덱스 만들고 &#39;아이유&#39;를 찾을 때(<strong>인덱스O</strong>)</span></p>
<ul>
<li>인덱스 검색(Index Scan)</li>
<li><code>Execution Plan(실행 계획)</code>탭 클릭: Non-Unique Key Lookup(인덱스를 통해 결과를 찾음)<pre><code class="language-sql">CREATE INDEX idx_member_name ON member(member_name);
SELECT * FROM member WHERE member_name=&#39;아이유&#39;;</code></pre>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>뷰(view)</strong>: &#39;가상의 테이블&#39;</p>
<ul>
<li>뷰는 실제 데이터를 가지고 있지 않고, 진짜 테이블에 링크된 개념</li>
<li>윈도우즈 운영체제의 &#39;바로 가기 아이콘&#39;과 비슷한 개념</li>
<li><span style="color:red">ex. 회원 테이블과 연결되는 회원 뷰(member_view) 만들기</span><pre><code class="language-sql">CREATE VIEW member_view
AS
  SELECT * FROM member;</code></pre>
</li>
<li><span style="color:red">회원 뷰(member_view) 접근하기</span><pre><code class="language-sql">SELECT * FROM member_view;</code></pre>
</li>
<li>뷰의 장점은 보안 도움, 긴 SQL 문을 간략화</li>
</ul>
</li>
<li><p><strong>스토어드 프로시저</strong>: MySQL에서 제공하는 프로그래밍 기능</p>
<ul>
<li>SQL을 묶는 개념, 프로그래밍 언어(ex. C, 자바, 파이썬)에서 사용되는 연산식, 조건문, 반복문 등 사용 가능</li>
<li><span style="color:red">ex. 스토어드 프로시저 만들기</span><ul>
<li><span style="color:red"><code>DELIMITER // ~ DELIMITER ;</code></span> 문은 첫 행과 마지막 행에 구분 문자</li>
<li><span style="color:red"><code>CREATE PROCEDURE</code></span> 스토어드 프로시저 이름 지정</li>
<li><span style="color:red"><code>BEGIN</code> 과 <code>END</code> 사이에 SQL 문</span><pre><code class="language-sql">DELIMITER //
CREATE PROCEDURE myProc()
BEGIN
  SELECT * FROM member WHERE member_name=&#39;나훈아&#39;;
  SELECT * FROM product WHERE product_name=&#39;삼각김밥&#39;;
END //
DELIMITER ;</code></pre>
</li>
</ul>
</li>
<li>스토어드 프로시저 호출하기: <span style="color:red"><code>CALL</code> 문</span><pre><code class="language-sql">CALL myProc()</code></pre>
</li>
<li>스토어드 프로시저 삭제하기: <span style="color:red"><code>DROP PROCEDURE</code> 문</span><pre><code class="language-sql">DROP PROCEDURE myProc;</code></pre>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="📌-참고문헌">📌 참고문헌</h2>
<p>우재남. (2021). 혼자 공부하는 SQL. 한빛미디어. p24-p99.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[맥북 환경설정-1]]></title>
            <link>https://velog.io/@so-kr/%EB%A7%A5%EB%B6%81-%ED%99%98%EA%B2%BD%EC%84%A4%EC%A0%95-1</link>
            <guid>https://velog.io/@so-kr/%EB%A7%A5%EB%B6%81-%ED%99%98%EA%B2%BD%EC%84%A4%EC%A0%95-1</guid>
            <pubDate>Thu, 22 Sep 2022 17:11:30 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💻 컴퓨터 : 맥북 M1 Pro
💡 유튜브 노마드 코더 Nomad Coders의 <a href="ttps://www.youtube.com/watch?v=B26yiuC5zPM&amp;t=647s">개발자를 위한 M1 풀옵션 맥북프로 세팅!
</a>을 참고하여 작성함(꼭! 유튜브를 시청하고 Homebrew를 설치하는 것을 권장함)</p>
</blockquote>
<h2 id="homebrew-설치하기">Homebrew 설치하기</h2>
<ul>
<li>1) Homebrew 사이트에서 아래의 명령어를 복사하기(command+C키)<ul>
<li><a href="https://brew.sh/index_ko">https://brew.sh/index_ko</a><pre><code class="language-bash">/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;</code></pre>
</li>
</ul>
</li>
<li>2) 터미널 창 실행하고 명령어 붙여넣고(command+V키) return키 누르기</li>
<li>3) <code>==&gt; Password:</code>에서 맥북 계정 Password 입력하고 return키 누르기</li>
<li>4) <code>Press RETURN to continue or any other key to about:</code>에서 return키 누르기</li>
<li>5) <code>==&gt; Next steps:</code>에 있는 아래의 명령어 두 줄을 각각 복사하고 붙여넣기<pre><code class="language-bash">echo &#39;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&#39; &gt;&gt; /Users/사용자/.zprofile
</code></pre>
</li>
</ul>
<p>eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;</p>
<pre><code>- 6) 터미널 재실행 후 아래의 명령어를 입력하여 설치가 잘 되었는지 확인하기
```bash
brew</code></pre><ul>
<li>7) Homebrew로 다양한 어플리케이션 설치하기<ul>
<li>예를 들면, <code>brew install --cask</code>로 VSCode, 크롬, iterm2 설치<pre><code class="language-bash">brew install --cask visual-studio-code google-chrome iterm2</code></pre>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>