<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>cl-song.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Tue, 08 Nov 2022 06:54:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. cl-song.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cl-song" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[코어자바스크립트] 01. 데이터 타입]]></title>
            <link>https://velog.io/@cl-song/%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-01.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@cl-song/%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-01.-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</guid>
            <pubDate>Tue, 08 Nov 2022 06:54:44 GMT</pubDate>
            <description><![CDATA[<h2 id="01-데이터-타입의-종류">01. 데이터 타입의 종류</h2>
<p><strong>데이터 타입(data type)</strong></p>
<ul>
<li>기본형(Primary type)<ul>
<li>숫자(Number)</li>
<li>문자(String)</li>
<li>불리언(Boolean)</li>
<li>null</li>
<li>undefined</li>
<li>Symbol<br></li>
</ul>
</li>
<li>참조형(Reference type)<ul>
<li>객체(Object)<ul>
<li>배열(Array)</li>
<li>함수(Function)</li>
<li>날짜(Date)</li>
<li>정규표현식(RegExp)</li>
<li>Map, WeakMap, Set, WeakSet</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>일반적으로 기본형은 할당이나 연산시 복제되고, 참조형은 참조된다.
<code>기본형은 값이 담긴 주솟값을 바로 복제</code>하는 반면 <code>참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제</code>한다.</p>
<p>기본형을 불변성(immutability)을 띈다.</p>
<h2 id="02-데이터-타입에-관한-지식">02. 데이터 타입에 관한 지식</h2>
<h3 id="1-2-1-메모리와-데이터">1-2-1 메모리와 데이터</h3>
<p>| 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | (= 1byte = 8bit)</p>
<p>각 비트는 고유한 식별자를 지니고, 바이트 역시 시작하는 비트의 식별자로 위치를 파악할 수 있다. 
모든 데이터는 바이트 단위의 식별자, 더 정확하게는 <code>메모리 주솟값(memory address)</code>를 통해 서로 구분하고 연결할 수 있다.</p>
<h3 id="1-2-2-식별자와-변수">1-2-2 식별자와 변수</h3>
<ul>
<li>변수: 변할 수 있는 <u>무언가(데이터)</u></li>
<li>식별자: 어떤 데이터를 식별하는 데 사용하는 이름, 즉 변수명</li>
</ul>
<h2 id="03-변수-선언과-데이터-할당">03. 변수 선언과 데이터 할당</h2>
<h3 id="1-3-1-변수-선언">1-3-1 변수 선언</h3>
<pre><code class="language-javascript">var a;</code></pre>
<p><code>변수란 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇이다.</code></p>
<h3 id="1-3-2-데이터-할당">1-3-2 데이터 할당</h3>
<pre><code class="language-javascript">var a;
a = &#39;abc&#39;;

var a = &#39;abc&#39;;</code></pre>
<p><strong>데이터 할당에 대한 메모리 영역의 변화</strong></p>
<ol>
<li>변수 영역에서 빈 공간(@1003)을 확보한다.</li>
<li>확보한 공간의 식별자를 a로 지정한다.</li>
<li>데이터 영역의 빈 공간(@5004)에서 문자열 &#39;abc&#39;를 저장한다.</li>
<li>변수 영역에서 a라는 식별자를 검색한다(@1003)</li>
<li>앞서 저장한 문자열의 주소 (@5004)를 @1003의 공간에 대입한다.</li>
</ol>
<p><strong>왜 변수 영역에 값을 직접 대입하지 않고 굳이 번거롭게 한 단게를 더 거치는 걸까?</strong>
기존 문자열에 어떤 변환을 가하든 무조건 새로 만들어 별도의 공간에 저장한다.</p>
<p>예를 들어 500 개의 변수를 생성 후 모든 변수에 숫자 5를 할당한다고 했을 때
각 변수 공간마다 숫자 5를 할당하려고 한다면 4000(500개의 변수 * 숫자 8비트)바이트를 써야 한다. 
그 대신 5를 별도의 공간에 저장하고 해당 주소만 입력한다면? 
1008(500개의 변수 * 2주소 공간 + 숫자 8비트)바이트만 이용하면 된다. 
이처럼 <code>변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아진다.</code></p>
<h2 id="04-기본형-데이터와-참조형-데이터">04. 기본형 데이터와 참조형 데이터</h2>
<h3 id="1-4-1-불변값">1-4-1 불변값</h3>
<p>변수와 상수를 구분하는 성질은 &#39;변경 가능성&#39;이다.(바꿀수 있으면 변수, 없으면 상수)
변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리이다. 한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부가 관건이다.</p>
<p>반면 <code>불변성 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역 메모리</code>입니다.
<code>기본형 데이터인 숫자, 문자열, boolean, null, undefined, Symbol은 모두 불변값이다.</code></p>
<hr>
<pre><code class="language-javascript">var a = &#39;abc&#39;;
a = a + &#39;def&#39;;

var b = 5;
var c = 5;
b = 7;</code></pre>
<p>변수 a에 문자열 &#39;abc&#39;를 할당했다가 뒤에 &#39;def&#39;를 추가하면 기존의 &#39;abc&#39;가 &#39;abcdef&#39;로 바뀌는 것이 아니라 새로운 문자열 &#39;abcdef&#39;를 만들어 그 주소를 변수 a에 저장한다.
&#39;abc&#39;와 &#39;abcdef&#39;는 완전히 별개의 데이터이다.</p>
<p>변수 b에 숫자 5를 할당한다. 그러면 컴퓨터는 일단 데이터 영역에서 5를 찾고, 없으면 데이터 공간을 하나 만들어 저장한다. 그 주소를 b에 저장한다.
변수 c에 같은 수인 5를 할당하려고 한다. 컴퓨터는 데이터 영역에서 이미 만들어 둔 값 5를 찾아 그 주소를 재활용한다.</p>
<p>변수 b의 값을 7로 바꾸려고 한다. 기존에 저장했던 7을 찾아 있으면 재활용하고, 없으면 새로 만들어 b에 저장한다.
결국 5와 7 모두 다른 값으로 변경할 수 없다.
변경은 새로 만드는 동작을 통해서만 이루어진다. 이것이 불변값의 성질이다.
한 번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한 영원히 변하지 않는다.</p>
<h3 id="1-4-2-가변값">1-4-2 가변값</h3>
<pre><code class="language-javascript">var obj1 = {
  a: 1,
  b: &#39;bbb&#39;
};
obj1.a = 2;</code></pre>
<p><strong>참조형 데이터의 할당 및 프로퍼티 재할당</strong></p>
<ol>
<li>변수 영역에서 빈 공간(@1002)을 확보하고, 그 주소의 이름을 obj1로 지정한다.</li>
<li>데이터 저장공간(@5001)에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이뤄진 데이터 그룹이다. 이 그룹 내부의 프로퍼티를 저장하기 위해 별도 변수 영역을 마련하고, 그 영역의 주소(@7103 ~ ?)를 @5001에 저장한다.</li>
<li>@7103 및 @7104에 각각 a와 b를 저장한다.</li>
<li>a의 값인 1을 데이터 영역에서 검색한다. 검색결과가 없으므로 @5003에 저장하고, 이 주소를 @7103에 저장한다. b의 값은 &#39;bbb&#39; 역시 임의로 @5004에 저장한 후, 이 주소를 @7104에 저장한다.</li>
<li>데이터 영역에서 숫자 2를 검색한다. 검색결과가 없으므로 @5005에 2를 저장하고 이 주소를 @7103에 저장한다.
=&gt; 변수 obj1이 바라보고 있는 주소는 @5001로 변하지 않았다. 즉 새로운 객체가 만들어진 것이 아니라 기존의 객체 내부의 값만 바뀌었다.</li>
</ol>
<hr>
<pre><code class="language-javascript">var obj = {
  x: 3,
  arr: [3, 4, 5]
};

obj.arr = &#39;str&#39;;</code></pre>
<p><strong>중첩 객체의 프로퍼티 할당 및 재할당</strong></p>
<ol>
<li>변수 영역의 빈 공간(@1002)를 확보하고, 그 주소의 이름을 obj로 지정한다.</li>
<li>임의의 데이터 공간(@5001)에 데이터를 저장하려는데, 여러 개의 변수와 값들로 이루어진 객체이다. 이 그룹의 각 변수들(x, arr)을 저장하기 위하여 별도의 변수 영역을 마련하고(@7103 ~ ?), 그 영역의 주소를 @5001에 저장한다.</li>
<li>@7103에 x를 @7104에 arr을 저장한다.</li>
<li>데이터 영역에서 숫자 3을 검색 후 없으므로 @5002에 저장하고 이 주소를 @7103에 저장한다.</li>
<li>@7104에 저장할 값은 배열이므로 이 그룹의 내부 프로퍼티를 저장하기 위해 별도의 변수 영역을 마련하고(@8104 ~ ?) 그 주소 정보를 @5003에 저장한다. 그 다음 @7104에 @5003을 저장한다.</li>
<li>배열의 요소가 3개 이므로 3개의 변수공간을 확보하고 @8104 ~ @8106에 각각 인덱스를 부여한다.</li>
<li>데이터 영역에서 숫자 3을 검색 후 그 주소(@5002)를 @8104에 저장한다.</li>
<li>데이터 영역에서 숫자 4를 검색 후 없으므로 @5004에 저장하고, 이 주소를 @8105에 저장한다.</li>
<li>데이터 영역에서 숫자 5를 검색 후 없으므로 @5005에 저장하고, 이 주소를 @8106에 저장한다.</li>
<li>@1002 -&gt; @5001 -&gt; @7103~? -&gt; @7104 -&gt; @5003
@5003에 저장된 값이 배열의 요소로 지정되어 있으므로, 값 &#39;str&#39;을 다른 데이터 영역에서 검색한 후 없으므로 @5006에 값을 저장하고, 그 주소를 @7104에 저장한다.
이때 @5003의 참조 카운트는 1 -&gt; 0이 됨에 따라 GC 대상이 되고, 연쇄적으로 @8104 ~ ? 데이터들도 같이 사라진다.</li>
</ol>
<h3 id="1-4-3-변수-복사-비교">1-4-3 변수 복사 비교</h3>
<h2 id="05-불변-객체">05. 불변 객체</h2>
<h3 id="1-5-1-불변-객체를-만드는-간단한-방법">1-5-1 불변 객체를 만드는 간단한 방법</h3>
<p><strong>어떤 상황에서 불변 객체가 필요할까?</strong>
값으로 전달받은 객체에 변경을 가하더라도 원본 객체는 변하지 않아야 하는 경우</p>
<h3 id="1-5-2-얕은-복사와-깊은-복사">1-5-2 얕은 복사와 깊은 복사</h3>
<p><code>얕은 복사(Shallow Copy)는 바로 아래 단계의 값만 복사하는 방법</code>이고, 
<code>깊은 복사(Deep Copy)는 내부의 모든 값들을 하나 하나 전부 복사하는 방법</code>이다.</p>
<p>어떤 객체를 복사할 때, 객체 내부의 모든 값을 복사해서 완전히 새로운 데이터를 만들고자 할 때,
<strong>객체의 프로퍼티 중에서 그 값이 기본형 데이터일 경우에는 그대로 복사</strong>하면 되지만 
<strong>참조형 데이터일 경우에는 다시 그 내부의 프로퍼티들을 복사</strong>해야 한다.</p>
<blockquote>
<p>깊은 복사 하는 방법</p>
</blockquote>
<ol>
<li>객체를 복사할 경우 내부 프로퍼티를 순회하여 그 값이 참조형일 경우 다시 그 내부의 프로퍼티들을 복사하도록 한다.</li>
<li>hasOwnProperty 메서드를 활용해 프로토타입 체이닝을 통해 상속된 프로퍼티를 복사하지 않게끔 한다.</li>
<li>객체를 JSON 문법으로 표혀된 문자열로 전환했다가 다시 JSON 객체로 바꾼다.<pre><code class="language-javascript">var copyObjectViaJSON = function(target) {
 return JSON.parse(JSON.stringify(target));
};</code></pre>
</li>
</ol>
<h2 id="06-undefined와-null">06. undefined와 null</h2>
<p>자바스크립트에서 &#39;없음&#39;을 나타내는 값 두 가지.
자바스크립트 엔진은 사용자가 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제로는 그렇게 하지 않았을 때 undefined를 반환한다.</p>
<ul>
<li>값을 대입하지 않은 변수(즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때)</li>
<li>객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때</li>
<li>return 문이 없거나 호출되지 않는 함수의 실행 결과</li>
</ul>
<p>&#39;비어있는 요소&#39;와 &#39;undefined를 할당한 요소&#39;는 출력 결과부터 다르며, &#39;비어있는 요소&#39;는 순회와 관련된 많은 배열 메서드들의 순회 대상에서 제외된다.
&#39;비어있음&#39;을 명시적으로 나타내고 싶을 때는 null을 사용한다.
null의 typeof 값은 object이므로(자바스크립트 버그) 어떤 변수가 실제로 null인지 아니면 undefined인지는 일치연산자(===)를 이용해야 정확히 판별할 수 있다.</p>
<h2 id="07정리">07.정리</h2>
<ul>
<li>자바스크립트 데이터 타입에는 기본형(불변값)과 참조형(가변값)이 있다.</li>
<li>변수는 변경 가능한 데이터가 담길 수 있는 공간이고, 식별자는 그 변수의 이름을 말한다.</li>
<li>변수를 선언하면 컴퓨터는 우선 메모리의 빈 공간에 식별자를 저장하고, 그 공간의 값은 undefined를 할당한다. 이후 그 변수에 기본형 데이터를 할당하려고 하면 별도의 공간에 데이터를 저장하고, 그 공간의 주소를 변수의 값 영역에 할당한다.</li>
<li>참조형 데이터를 할당하고자 할 경우 컴퓨터는 참조형 데이터 내부 프로퍼티들을 위한 변수 영역을 별도로 확보해서 확보된 주소를 변수에 연결하고, 다시 앞서 확보한 변수 영역에 각 프로퍼티의 식별자를 저장하고, 각 데이터를 별도의 공간에 저장해서 그 주소를 식별자들과 매칭시킨다.
이처럼 할당 과정에서 기본형과 차이가 생긴 이유는 참조형 데이터가 여러 개의 프로퍼티(변수)를 모은 &#39;그룹&#39;이기 때문이다. 그리고 이 차이로 인해 참조형 데이터를 &#39;가변값&#39;으로 여겨야만 하는 상황이 발생한다.</li>
<li>참조형 데이터를 가변값으로 여겨야하는 상황임에도 이를 불변값으로 사용하는 방법은<ol>
<li>프로퍼티들을 복사(깊은 복사)</li>
<li>라이브러리 사용</li>
</ol>
<strong>불변 객체는 자바스크립트에서 중요한 개념 중 하나이다.</strong></li>
<li>&#39;없음&#39;을 나타내는 값은 두 가지가 있는데, undefined는 어떤 변수에 값이 존재하지 않을 경우를 의미하고 null은 사용자가 명시적으로 &#39;없음&#39;을 표현하기 위해 대입한 값이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 테이블 조인]]></title>
            <link>https://velog.io/@cl-song/SQL-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%A1%B0%EC%9D%B8</link>
            <guid>https://velog.io/@cl-song/SQL-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%A1%B0%EC%9D%B8</guid>
            <pubDate>Mon, 24 Oct 2022 07:52:45 GMT</pubDate>
            <description><![CDATA[<h2 id="조인-이해하기">조인 이해하기</h2>
<ul>
<li>SQL 유용한 기능 중 하나는 데이터 검색 쿼리에서 바로 테이블 조인이 가능하다는 점이다.</li>
<li>조인은 SQL SELECT 문을 사용하여 수행할 수 있는데, SQL을 학습할 때 조인과 조인 문법을 잘 이해하는 것은 아주 중요하다.</li>
<li>조인을 효과적으로 사용하려면, 먼저 관계형 테이블과 관계형 데이터베이스 디자인을 이해해야 한다.</li>
</ul>
<h3 id="관계형-테이블-이해하기">관계형 테이블 이해하기</h3>
<p>관계형 데이터 베이스 디자인의 기본원리</p>
<ul>
<li>같은 데이터를 여러 곳에 저장하는 것은 좋지 않다.</li>
<li>관계형 테이블은 정보를 쪼개 여러 개의 테이블에 저장하도록 설계되었다.</li>
<li>테이블은 공통 열을 통해 연결된다.</li>
<li>유효한 데이터만이 관계형 열에 삽입될 수 있다.</li>
</ul>
<br>
EX)

<table>
<thead>
<tr>
<th align="center">판매처 정보 (Vendors) 테이블</th>
<th align="center"></th>
</tr>
</thead>
<tbody><tr>
<td align="center">판매처1</td>
<td align="center"><strong>판매처 ID = 식별자1</strong></td>
</tr>
<tr>
<td align="center">판매처2</td>
<td align="center"><strong>판매처 ID = 식별자2</strong></td>
</tr>
<tr>
<td align="center">판매처3</td>
<td align="center"><strong>판매처 ID = 식별자3</strong></td>
</tr>
</tbody></table>
<p>각 행은 판매처를 구별할 수 있는 <code>고유한 식별자</code>를 갖는다. 이런 값을 <code>기본키(Primary Key)</code>라고 부른다.
여기서는 판매처 ID를 기본 키로 사용했다.</p>
<table>
<thead>
<tr>
<th align="center">&nbsp;제품 정보 (Products) 테이블&nbsp;</th>
<th align="center"></th>
</tr>
</thead>
<tbody><tr>
<td align="center">제품 정보1</td>
<td align="center"><strong>판매처 ID = 식별자1</strong></td>
</tr>
<tr>
<td align="center">제품 정보2</td>
<td align="center"><strong>판매처 ID = 식별자2</strong></td>
</tr>
<tr>
<td align="center">제품 정보3</td>
<td align="center"><strong>판매처 ID = 식별자3</strong></td>
</tr>
</tbody></table>
<p>판매처 ID는 Vendors 테이블과 Products 테이블을 연결하는데, 이 키를 이용해 Vendors 테이블에서 제품 정보를 찾을 수 있다.</p>
<ul>
<li>판매처 정보가 절대 반복되지 않기 때문에 시간과 공간이 낭비되지 않는다.</li>
<li>판매처 정보가 변경되더라도 Vendors 테이블에 있는 하나의 행만 업데이트 하면 된다.
관련된 테이블에 있는 데이터는 변경되지 않는다.</li>
<li>데이터가 반복되지 않기 때문에 사용한 데이터는 늘 일관성을 갖는다. 그렇게 때문에 데이터 보고와 조작이 더 간단해진다.</li>
</ul>
<h3 id="왜-조인을-사용할까">왜 조인을 사용할까?</h3>
<p>조인은 SELECT 문 안에서 테이블을 연결할 때 사용한다.
특별한 문법을 사용해서 여러 개의 테이블을 조인하면, 하나의 결과를 가져올 수 있다.
조인은 각 테이블에서 적절한 행을 서로 연결하는 역할을 한다.
=&gt; 조인은 데이터베이스 테이블에서 실제로 존재하지 않는다. DBMS에서 필요할 때 생성하고, 쿼리가 수행되는 동안에만 유지된다.</p>
<h2 id="조인-생성하기">조인 생성하기</h2>
<h3 id="where-절의-중요성">WHERE 절의 중요성</h3>
<p>두 개의 테이블을 조인할 때, 할 일은 첫 번째 테이블의 행과 두 번째 테이블을 행으로 짝을 짓는 것이다. WHERE 절은 필터로 동작해 지정한 조건과 일치하는 행만 가져온다. <u>WHERE 절이 없다면 첫 번째 테이블에 있는 모든 행은 두 번째 테이블에 있는 모든 행과 짝이 된다.</u>
따라서 <code>조인을 사용할 때 WHERE 절이 있는지 꼭 확인하자.</code></p>
<pre><code class="language-sql">SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;</code></pre>
<p>여기서 사용한 조인은 동등 조인 혹은 이퀴 조인(Equi-Join)이라고 하는데, 이 조인은 두 개의 테이블에 있는 공통 열의 값이 같은 것을 결과로 가져온다. 이런 종류의 조인을 내부 조인(Inner Join)이라고도 부른다.</p>
<p>조인 타입을 표시할 때는 다른 문법을 사용해야 한다.</p>
<h3 id="내부-조인inner-join">내부 조인(Inner Join)</h3>
<pre><code class="language-sql">SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;</code></pre>
<h3 id="여러-개의-테이블-조인하기">여러 개의 테이블 조인하기</h3>
<pre><code class="language-sql">SELECT prod_name, vend_name, prod_price, quantity
FROM OrderItems, Products, Vendors
WHERE Products.vend_id = Vendors.vend_id
AND OrderItems.prod_id = Products.prod_id
AND order_num = 20007;</code></pre>
<p>✔️ <strong>성능에 대한 고려</strong>
테이블을 연결하는 조인은 많은 테이블을 조인할 수록 성능이 저하되므로 불필요한 테이블을 조인하지 않도록 주의하자.</p>
<hr>
<h2 id="도전-과제">도전 과제</h2>
<ol>
<li>Customers 테이블에서 고객명(cust_name)과 Orders 테이블에서 관련된 주문 번호(order_num)를 가져와, 그 결과를 고객명 그리고 주문 번호순으로 정렬하는 SQL문을 작성하라.
실제로 간단한 이퀴 조인 문법을 사용하여 한 번, 내부 조인을 사용하여 한 번 더 작성해보자.
```sql</li>
</ol>
<p>-- 이퀴 조인
SELECT cust_name, order_num
FROM Customers, Orders
WHERE Customers.cust_id = Orders.cust_id
ORDER BY cust_name, order_num;</p>
<p>-- 내부 조인
SELECT cust_name, order_num
FROM Customers INNER JOIN Orders
ON Customers.cust_id = Orders.cust_id
ORDER BY cust_name, order_num;</p>
<pre><code>2. 고객명과 주문 번호 외 OrderTotal이라는 이름의 세 번째 열을 추가해 보자. OrderTotal에는 각 주문의 총가격이 포함되어 있다. 이를 위해 2가지 방법이 있다. 
OrderItems테이블에서 서브쿼리를 사용해 OrderTotal 열을 생성하는게 첫 번째 방법이다.
두 번째는 기존 테이블에 OrderItems 테이블을 조인한 다음 그룹 함수를 사용할 수 있다.
완전한 열 이름 사용이 필요할 수도 있다는 점에 유의하자.
`⭐열 이름이 같을 경우 오류가 나므로 완전한 열 이름을 사용하자⭐`
```sql
-- 서브쿼리
SELECT cust_name, order_num, ( SELECT SUM(quantity * item_price) 
                               FROM OrderItems
                               WHERE Orders.order_num = OrderItems.order_num ) AS OrderTotal
FROM Customers, Orders
WHERE Customers.cust_id = Orders.cust_id
ORDER BY cust_name, order_num;

-- 그룹 함수
SELECT cust_name, Orders.order_num, SUM(quantity * item_price) AS OrderTotal
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND Orders.order_num = OrderItems.order_num
GROUP BY cust_name, Orders.order_num
ORDER BY cust_name, order_num;</code></pre><ol start="3">
<li><p>11장에 있는 도전 과제 2를 다시보자. 제품 BR01이 주문된 날짜를 가져오는 SQL문을 작성하라. 이번에는 조인과 간단한 이퀴 조인 문법을 사용한다. 결과는 11장과 같아야 한다.</p>
<pre><code class="language-sql">SELECT cust_id, order_date
FROM Orders, OrderItems
WHERE Orders.order_num = OrderItems.order_num 
AND prod_id = &#39;BR01&#39;
ORDER BY order_date;</code></pre>
</li>
<li><p>11장 도전 과제 3을 ANSI 내부 조인 문법을 사용해 다시 작성해 보자. 도전 과제 3에서 작성한 코드는 2개의 중첩된 서브쿼리를 사용하였다. 다시 만들려면, 이 장 앞 예제에서 설명한 것처럼 두 개의 내부 조인이 있어야 한다. 마지막으로 prod_id로 필터링할 WHERE 절을 잊지 말기 바란다.
(11장 도전 과제3: prod_id가 BR01을 구매한 모든 고객의 이메일주소를 가져오자)
<code>⭐두 개의 내부 조인 사용법을 익혀두자⭐</code></p>
</li>
</ol>
<pre><code class="language-sql">SELECT cust_email
FROM Customers
INNER JOIN Orders ON Customers.cust_id = Orders.cust_id
INNER JOIN OrderItems ON Orders.order_num = OrderItems.order_num
WHERE prod_id = &#39;BR01&#39;;</code></pre>
<ol start="5">
<li>조인과 그룹 함수, 그룹핑을 모두 섞어 좀 더 재밌게 만들어보자.
10장으로 돌아가 보면 1000 이상의 값을 가진 주문 번호를 찾는 도전 과제가 있었다.
결과는 유용하긴 했지만, 그 주문한 고객의 이름을 찾으면 실용성이 한층 더 높아질 수 있다.
조인을 사용하여 customers 테이블에서 고객명(cust_name), 그리고 OrderItems테이블에서 모든 주문의 합계를 가져오는 SQL 문을 작성하라. 이 테이블을 조인하려면 Orders 테이블도 포함해야 한다. GROUP BY와 HAVING 절을 사용해야 한다는 것과 고객명으로 정렬하는 것도 잊지 말자. 간단한 이퀴 조인이나 ANSI 내부 조인 문법을 사용해보자.
```sql</li>
</ol>
<p>-- 이퀴 조인
SELECT cust_name, SUM(quantity * item_price) AS sum_total
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND Orders.order_num = OrderItems.order_num
GROUP BY cust_name
HAVING SUM(quantity * item_price) &gt;= 1000
ORDER BY cust_name;</p>
<p>-- 내부 조인
SELECT cust_name, SUM(quantity * item_price) AS sum_total
FROM Customers
INNER JOIN Orders ON Customers.cust_id = Orders.cust_id
INNER JOIN OrderItems ON Orders.order_num = OrderItems.order_num
GROUP BY cust_name
HAVING SUM(quantity * item_price) &gt;= 1000
ORDER BY cust_name;
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 서브쿼리 사용하기]]></title>
            <link>https://velog.io/@cl-song/SQL-%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/SQL-%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 20 Oct 2022 05:46:42 GMT</pubDate>
            <description><![CDATA[<h2 id="서브쿼리-이해하기">서브쿼리 이해하기</h2>
<ul>
<li>서브쿼리는 쿼리 안에 있는 쿼리를 말한다.</li>
<li>서브쿼리는 항상 안에 있는 쿼리를 먼저 처리하고, 바깥 쪽에 있는 쿼리를 처리한다.</li>
<li>서브쿼리는 WHERE 절과 IN 절에서 가장 많이 사용되고, 계산 필드를 구하기 위해서도 사용된다.</li>
<li>서브쿼리가 항상 최선의 선택은 아니다.(가장 효율적인 것은 아니다. 다음 장의 <u>조인</u> 참고!) </li>
</ul>
<h3 id="서브쿼리로-필터링하기">서브쿼리로 필터링하기</h3>
<pre><code class="language-sql">SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id IN( SELECT cust_id
                  FROM Orders
                  WHERE order_num IN ( SELECT order_num
                                       FROM OrderItmes
                                       WHERE prod_id = &#39;RGAN01&#39; ));</code></pre>
<h3 id="계산-필드로-서브쿼리-사용하기">계산 필드로 서브쿼리 사용하기</h3>
<p>```sql
SELECT cust_name, cust_state, ( SELECT COUNT(<em>)
                                FROM Orders
                                WHERE Orders.cust_id = Customers.cust_id ) AS orders
FROM Customers
ORDER BY cust_name;
/</em> 이 쿼리는 Customers 테이블에서 고객 이름, 주소, 주문 수량을 가져온다.
orders는 괄호로 묶인 서브쿼리에 의해 구해진 계산필드이다.
서브쿼리에 있는 WHERE 절은 테이블과 열 이름을 모두 명시하는 
완전한 열 이름(Fully Qualified Column Name)을 사용하였다. =&gt; 열 이름이 모호할 때 사용 */</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 데이터 그룹핑]]></title>
            <link>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B7%B8%EB%A3%B9%ED%95%91</link>
            <guid>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B7%B8%EB%A3%B9%ED%95%91</guid>
            <pubDate>Tue, 18 Oct 2022 08:19:02 GMT</pubDate>
            <description><![CDATA[<h2 id="데이터-그룹핑-이해하기">데이터 그룹핑 이해하기</h2>
<ul>
<li>그룹핑은 데이터를 논리적으로 나눠주기 때문에 <u>각 그룹에 대한 집계 연산을 수행</u>할 수 있다.</li>
</ul>
<h3 id="그룹-생성하기-group-by-절">그룹 생성하기: GROUP BY 절</h3>
<pre><code class="language-sql">SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id;
-- GROUP BY 절에게 vend_id로 그룹핑하고 데이터를 정렬하라고 명령한다.</code></pre>
<p>GROUP BY 절을 사용하면 자동으로 각 그룹에 대해 계산하기 때문에, 계산할 그룹을 따로 명시할 필요가 없다. 
GROUP BY 절은 DBMS에게 먼저 데이터를 그룹핑한 후, 각각의 그룹에 대해 계산하라고 지시한다.</p>
<h4 id="규칙">규칙</h4>
<ul>
<li>GROUP BY 절에는 원하는 만큼의 열을 써서, 중첩(nested) 그룹을 만들 수 있다. 이 방식은 데이터를 그룹핑하는 방식을 좀 더 세밀하게 제어할 수 있게 해준다.</li>
<li>GROUP BY 절에 중첩된 그룹이 있다면, 데이터는 마지막으로 지정된 그룹에서 요약된다. 즉, 지정된 열은 그룹핑할 때 같이 측정된다.</li>
<li>GROUP BY 절에 있는 열은 가져오는 열이거나, 그룹 함수는 아니면서 유효한 수식이어야 한다. SELECT 절에서 수식을 사용한다면, GROUP BY 절에도 같은 수식을 사용해야 한다. 별칭은 사용할 수 없다.</li>
<li>대부분의 SQL 실행 환경에서는 GROUP BY 절에서 문자나 메모와 같은 가변형 길이의 데이터형은 사용할 수 없다.</li>
<li>그룹 함수 명령문을 제외하고 SELECT절에 있는 모든 열은 GROUP BY 절에 존재해야 한다.</li>
<li>그룹핑하는 열의 행에 NULL 값이 있다면, NULL도 그룹으로 가져온다.
여러 행이 NULL값을 가진다면, 모두 함께 그룹핑된다.</li>
<li>GROUP BY 절은 WHERE 절 뒤에, ORDER BY 절 앞에 와야 한다.</li>
</ul>
<h3 id="그룹-필터링-having-절">그룹 필터링: HAVING 절</h3>
<p>WHERE 절의 모든 유형은 HAVING 절에서도 사용이 가능하다.
차이점은 WHERE 절은 행을 필터링하고, HAVING 절은 그룹을 필터링한다.
WHERE 절은 데이터가 그룹핑되기 전에 필터링하고, HAVING 절은 데이터가 그룹핑된 후에 필터링한다.
<strong>GROUP BY 절이 있을 때만 HAVING 절을 사용하고, 행 단위로 필터링 할때는 WHERE 절을 사용하자!</strong></p>
<pre><code class="language-sql">SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) &gt;= 2;

-- Products 테이블에서 가격이 4달러 이상인 제품을 2개이상 가진 판매처를 가져와라
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
WHERE prod_price &gt;= 4
GROUP BY vend_id
HAVING count(*) &gt;= 2;</code></pre>
<h3 id="그룹핑과-정렬">그룹핑과 정렬</h3>
<table>
<thead>
<tr>
<th align="left">ORDER BY</th>
<th align="left">GROUP BY</th>
</tr>
</thead>
<tbody><tr>
<td align="left">결과를 정렬한다.</td>
<td align="left">행을 그룹핑한다. <strong>결과는 그룹 순서대로 출력되지 않을 수 있다.</strong></td>
</tr>
<tr>
<td align="left">가져오지 않은 열이라도 사용할 수 있다.</td>
<td align="left">선택된 열이나 수식만 사용할 수 있고, 선택된 열이나 수식을 꼭 사용해야 한다.</td>
</tr>
<tr>
<td align="left">필수 항목은 아니다.</td>
<td align="left">그룹 함수와 함께 사용하는 열(또는 수식)이 있는 경우 필수 항목이다.</td>
</tr>
<tr>
<td align="left">GROUP BY 절을 사용할 때마다 ORDER BY 절을 명시해야 한다.</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">그렇게 해야 데이터가 제대로 정렬되었다고 확신할 수 있다.</td>
<td align="left"></td>
</tr>
</tbody></table>
<pre><code class="language-sql">-- Orderitems 테이블에서 세 개 이상의 제품을 주문한 경우의 주문 번호와 주문 수량을 항목 수로 정렬하여 가져와라.
SELECT order_num, COUNT(*) AS items
FROM Orderitems
GROUP BY order_num
HAVING COUNT(*) &gt;= 3
ORDER BY items, order_num;</code></pre>
<p>✔️ <strong>SELECT문 순서</strong>
SELECT 가져올 열이나 순서
FROM 데이터를 가져올 테이블
WHERE 행 레벨 필터링
GROUP BY 그룹 지정
HAVING 그룹 레벨 필터링
ORDER BY 정렬 순서</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 데이터 요약]]></title>
            <link>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9A%94%EC%95%BD</link>
            <guid>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9A%94%EC%95%BD</guid>
            <pubDate>Fri, 14 Oct 2022 07:08:39 GMT</pubDate>
            <description><![CDATA[<h2 id="그룹-함수-사용하기">그룹 함수 사용하기</h2>
<ul>
<li>데이터를 실제로 가져오지 않고 분석이나 보고를 목적으로 <u>데이터를 요약해야 할 때 사용</u>한다.<ul>
<li>테이블에 있는 행의 수(또는 조건을 만족하거나 특정한 값을 가진 행의 수)를 확인하려고 할 때</li>
<li>테이블에 있는 여러 행의 합계를 구하고자 할 때</li>
<li>테이블에서 가장 큰 값, 가장 작은 값, 평균값을 구하고자 할 때</li>
</ul>
</li>
</ul>
<h3 id="avg-함수">AVG() 함수</h3>
<pre><code class="language-sql">-- 테이블에 있는 행의 수와 각 행의 합을 계산해 특정 열의 평균값을 반환한다.
-- AVG(열이름) 함수는 하나의 열에서만 사용 가능하다.
-- AVG(열이름) 함수는 NULL 값을 가진 행은 무시한다.
SELECT AVG(prod_price) AS avg_price
FROM Products
WHERE vend_id = &#39;DLL01&#39;;</code></pre>
<h3 id="count-함수">COUNT() 함수</h3>
<pre><code class="language-sql">-- COUNT() 함수는 행의 개수를 세는 함수이다.
-- 모든 행의 수를 세기 위해 COUNT(*) 함수를 사용할 때는 NULL 값을 가진 열을 포함한다.
-- 지정한 열에 값이 있는 행의 수를 세기 위해 COUNT(열 이름) 함수를 사용할 때는 NULL 값을 가진 행은 무시한다.
SELECT COUNT(*) AS num_cust
FROM Customers;

SELECT COUNT(cust_email) AS num_cust
FROM Customers;</code></pre>
<h3 id="max-함수">MAX() 함수</h3>
<pre><code class="language-sql">-- MAX(열이름) 함수는 지정한 열에서 가장 큰 값을 반환한다.
-- MAX(열이름) 함수는 NULL 값을 가진 행은 무시한다.
SELECT MAX(prod_price) AS max_price
FROM Products;
-- 문자열 데이터에 MAX() 함수는 데이터가 열로 정렬된 경우 가장 마지막에 있는 행을 반환한다.`</code></pre>
<h3 id="min-함수">MIN() 함수</h3>
<pre><code class="language-sql">-- MIN(열이름) 함수는 지정한 열에서 가장 작은 값을 반환한다.
-- MIN(열이름) 함수는 NULL 값을 가진 행은 무시한다.
SELECT MIN(prod_price) AS min_price
FROM Products;
-- 문자열 데이터에 MIN() 함수는 데이터가 열로 정렬된 경우 가장 처음에 있는 행을 반환한다.</code></pre>
<h3 id="sum-함수">SUM() 함수</h3>
<pre><code class="language-sql">-- SUM(열이름) 함수는 지정한 열의 합을 구한다.
-- SUM(열이름) 함수는 NULL 값을 가진 행은 무시한다.
SELECT SUM(quantity) AS item_ordered
FROM OrderItems
WHERE order_item = &#39;1&#39;;

SELECT SUM(quantity * item_price) AS total_price
FROM OrderItems
WHERE order_num = 20005;</code></pre>
<h2 id="중복되는-값에-대한-그룹-함수">중복되는 값에 대한 그룹 함수</h2>
<ul>
<li>ALL은 기본값이므로 아무런 키워드도 쓰지 않으면 모든 행에 대해 계산을 수행한다.</li>
<li>중복되는 값을 제거하기 위해 DISTICT 키워드를 사용한다.</li>
</ul>
<pre><code class="language-sql">SELECT AVG(DISTINCT prod_price) AS avg_price
FROM Products
WHERE vend_id=&#39;DLL01&#39;;</code></pre>
<h2 id="그룹-함수-결합하기">그룹 함수 결합하기</h2>
<pre><code class="language-sql">SELECT COUNT(*) AS num_items,
        AVG(DISTINCT prod_price) AS avg_price,
        MIN(prod_price) AS min_price,
        MAX(prod_price) AS max_price
FROM Products;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 데이터 조작 함수 사용하기]]></title>
            <link>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%EC%9E%91-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%EC%9E%91-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 14 Oct 2022 01:31:07 GMT</pubDate>
            <description><![CDATA[<h2 id="함수-이해하기">함수 이해하기</h2>
<ul>
<li>함수는 데이터를 다룰 때 쓰는데, 보통 데이터를 변환하거나 조작할 수 있게 해준다.</li>
<li>SQL 함수는 DBMS간 호환성이 매우 낮아 문제의 소지가 있다.
=&gt; 특정 SQL 구현에 맞추어 짠 코드가 다른 DBMS에서는 동작하지 않을 수 있다.</li>
</ul>
<h2 id="함수-사용하기">함수 사용하기</h2>
<h3 id="문자열-조작-함수">문자열 조작 함수</h3>
<table>
<thead>
<tr>
<th align="left">함수</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="left">LEFT()</td>
<td align="left">문자열 왼쪽에서부터 문자열 일부를 추출</td>
</tr>
<tr>
<td align="left">LENGTH() or DATALENGTH() or LEN()</td>
<td align="left">문자열의 길이를 반환</td>
</tr>
<tr>
<td align="left">LOWER()</td>
<td align="left">문자열을 소문자로 변환</td>
</tr>
<tr>
<td align="left">LTRIM()</td>
<td align="left">문자열의 왼쪽에 있는 공백 문자를 삭제</td>
</tr>
<tr>
<td align="left">RIGHT()</td>
<td align="left">문자열 오른쪽에서부터 문자열 일부를 추출</td>
</tr>
<tr>
<td align="left">RTRIM()</td>
<td align="left">문자열의 오른쪽에 있는 공백 문자를 삭제</td>
</tr>
<tr>
<td align="left">SUBSTR() or SUBSTRING()</td>
<td align="left">문자열의 일부를 추출</td>
</tr>
<tr>
<td align="left">SOUNDEX()</td>
<td align="left">문자열의 SOUNDEX 값을 반환</td>
</tr>
<tr>
<td align="left">UPPER()</td>
<td align="left">문자열을 대문자로 변환</td>
</tr>
</tbody></table>
<h3 id="날짜와-시간-조작-함수">날짜와 시간 조작 함수</h3>
<p><strong>날짜와 시간 조작 함수는 매우 중요한 기능이지만, 일관성이 매우 적고, 호환이 거의 되지 않는다.</strong></p>
<table>
<thead>
<tr>
<th align="left">함수</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="left">DATEPART(반환할 데이터, 시간) or DATE_PART()</td>
<td align="left">날짜 일부분을 반환</td>
</tr>
<tr>
<td align="left">YEAR()</td>
<td align="left">연도 반환</td>
</tr>
</tbody></table>
<p>EXTRACT()나 BETWEEN 연산자로도 같은 작업 수행이 가능하다.</p>
<h3 id="수치-조작-함수">수치 조작 함수</h3>
<table>
<thead>
<tr>
<th align="left">함수</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="left">ABS()</td>
<td align="left">숫자의 절대값을 반환</td>
</tr>
<tr>
<td align="left">COS()</td>
<td align="left">숫자의 코사인값을 반환</td>
</tr>
<tr>
<td align="left">EXP()</td>
<td align="left">숫자의 지숫값을 반환</td>
</tr>
<tr>
<td align="left">PI()</td>
<td align="left">숫자의 파이값을 반환</td>
</tr>
<tr>
<td align="left">SIN()</td>
<td align="left">숫자의 사인값을 반환</td>
</tr>
<tr>
<td align="left">SQRT()</td>
<td align="left">숫자의 제곱근을 반환</td>
</tr>
<tr>
<td align="left">TAN()</td>
<td align="left">숫자의 탄젠트값을 반환</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 계산 필드 생성하기]]></title>
            <link>https://velog.io/@cl-song/SQL-%EA%B3%84%EC%82%B0-%ED%95%84%EB%93%9C-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/SQL-%EA%B3%84%EC%82%B0-%ED%95%84%EB%93%9C-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 12 Oct 2022 08:05:56 GMT</pubDate>
            <description><![CDATA[<h2 id="계산-필드-이해하기">계산 필드 이해하기</h2>
<ul>
<li>테이블에 저장한 데이터와 응용 프로그램이 원하는 형식이 다른 경우 사용한다.<ul>
<li>두 정보가 서로 다른 테이블 열에 저장되어 있을 때</li>
<li>서로 다른 열에 저장되어 있지만, 응용 프로그램에서는 하나의 필드로 가져와야 할 때</li>
<li>열 데이터에는 대소문자가 섞여 있지만, 응용 프로그램에서는 모두 대문자로 출력해야 할 때</li>
<li>테이블 내에는 제품의 가격과 수량이 있지만, 최종 가격은 저장하지 않는다. 이 때 최종 가격이 필요할 때</li>
<li>테이블 내에 있는 데이터를 기반으로 합계, 평균, 도는 다른 계산값이 필요할 때</li>
</ul>
</li>
<li>계산 필드는 데이터베이스 테이블에 실제로 존재하지 않는다.
=&gt; 계산 필드는 SQL SELECT문에서 동적으로 생성되기 때문이다.</li>
</ul>
<h3 id="필드-연결하기">필드 연결하기</h3>
<pre><code class="language-sql">-- _SQL Server_
SELECT RTRIM(vend_name) + &#39; (&#39; + RTRIM(vend_country) + &#39;)&#39;
FROM Vendors
ORDER BY vend_name;

-- _Db2, Oracle, PostgreSQL, SQLite_
SELECT RTRIM(vend_name) || &#39; (&#39; || RTRIM(vend_country) || &#39;)&#39;
FROM Vendors
ORDER BY vend_name;

-- _MySQL, MariaDB_
SELECT Concat(vend_name , &#39; (&#39; , vend_country , &#39;)&#39;
FROM Vendors
ORDER BY vend_name;</code></pre>
<p><strong>TRIM 함수</strong></p>
<ul>
<li>RTRIM(): 문자열의 오른쪽에 있는 공백 제거</li>
<li>LTRIM(): 문자열의 왼쪽에 있는 공백 제거</li>
<li>TRIM(): 양쪽에 있는 공백 제거</li>
</ul>
<h3 id="별칭파생열-사용하기">별칭(파생열) 사용하기</h3>
<pre><code class="language-sql">/* 계산 필드는 단순한 하나의 값으로 이름이 없다.
클라이언트에서 호출할 수 있도록 별칭을 지원한다.
별칭은 AS 키워드를 사용하여 부여한다. */

SELECT RTRIM(vend_name) + &#39; (&#39; + RTRIM(vend_country) + &#39;)&#39;
-- SELECT RTRIM(vend_name) || &#39; (&#39; || RTRIM(vend_country) || &#39;)&#39;
-- SELECT Concat(vend_name , &#39; (&#39; , vend_country , &#39;)&#39;
AS vend_title
FROM Vendors
ORDER BY vend_name;</code></pre>
<h3 id="수학-계산-수행하기">수학 계산 수행하기</h3>
<p>-- 계산 필드는 가져온 데이터의 수학적 계산을 수행할 때도 자주 사용한다.</p>
<pre><code class="language-sql">SELECT prod_id, quantity, item_price, (quantity * item_price) AS expanded_price
FROM OrderItems
WHERE order_num = 20008;</code></pre>
<table>
<thead>
<tr>
<th align="center">연산자</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">+</td>
<td align="center">더하기</td>
</tr>
<tr>
<td align="center">-</td>
<td align="center">빼기</td>
</tr>
<tr>
<td align="center">*</td>
<td align="center">곱하기</td>
</tr>
<tr>
<td align="center">/</td>
<td align="center">나누기</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 와일드카드 문자를 이용한 필터링]]></title>
            <link>https://velog.io/@cl-song/SQL-%EC%99%80%EC%9D%BC%EB%93%9C%EC%B9%B4%EB%93%9C-%EB%AC%B8%EC%9E%90%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%ED%95%84%ED%84%B0%EB%A7%81</link>
            <guid>https://velog.io/@cl-song/SQL-%EC%99%80%EC%9D%BC%EB%93%9C%EC%B9%B4%EB%93%9C-%EB%AC%B8%EC%9E%90%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%ED%95%84%ED%84%B0%EB%A7%81</guid>
            <pubDate>Tue, 11 Oct 2022 00:42:16 GMT</pubDate>
            <description><![CDATA[<h2 id="like-연산자-사용하기">LIKE 연산자 사용하기</h2>
<ul>
<li>와일드카드란 여러 데이터에서 부분적으로 일치하는 값이 있는지 확인할 때 사용되는 특수문자이다.</li>
<li>와일드카드는 SQL WHERE 절에서 특별한 의미가 있는 문자이다.</li>
<li>검색 절에서 와일드카드를 사용하려면 반드시 LIKE연산자를 사용해야 한다.</li>
<li>LIKE는 뒤에 나오는 검색 패턴과 일치하는 데이터를 찾는 게 아니라 와일드카드를 사용해 비교한다.</li>
<li>와일드카드 검색은 텍스트 열(문자열)에서만 사용할 수 있다.</li>
</ul>
<h3 id="-와일드카드">% 와일드카드</h3>
<pre><code class="language-sql">/* %는 임의의 수의 문자를 의미한다.
특정 문자열을 포함한 열을 찾고 싶을 때 사용한다. */
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE &#39;Fish%&#39;;

SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE &#39;%bean bag%&#39;;</code></pre>
<h3 id="_-와일드카드">_ 와일드카드</h3>
<pre><code class="language-sql">/* _ 와일드카드는 단 한 개의 문자를 대신한다.
Db2에서는 _ 와일드카드가 지원되지 않는다. */
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE &#39;__ inch teddy bear%&#39;;</code></pre>
<h3 id="집합-와일드카드">집합([]) 와일드카드</h3>
<pre><code class="language-sql">/* [] 와일드카드는 문자들을 하나의 집합으로 지정해 사용하는데, 
이들 문자 중 하나는 지정된 위치(와일드카드가 지정한)의 문자와 반드시 일치하는 검색 결과를 가져온다.
집합 와일드카드는 일반적으로 지원되지 않으므로 DBMS 매뉴얼을 확인해야한다. */
SELECT cust_contact
FROM Customers
WHERE cust_contact LIKE &#39;[JM]%&#39;; -- J또는 M으로 시작하는 연락처 찾기
WHERE cust_contact LIKE &#39;[^JM]%&#39;; -- J또는 M으로 시작하지 않는 연락처 찾기
(= WHERE NOT cust_contact LIKE &#39;[JM]%;)</code></pre>
<blockquote>
<p><strong>후행 공백에 주의하자</strong>
예를 들어 50개의 문자를 넣을 수 있는 열에 길이가 17인 문자열을 저장하면, 열을 채우기 위해 33개의 공백이 추가될 수 있다.
문자열을 검색할 때 값에 공백이 추가되었다면, 끝나는 값이 공백이 되므로 검색패턴에 %를 추가하거나 함수를 이용해 공백을 제거한다.</p>
</blockquote>
<p>✔️ <strong>와일드카드 사용 팁</strong></p>
<ul>
<li>와일드카드를 남용해서는 안된다. 다른 검색 연산자 사용이 가능하다면 그것을 이용하라.</li>
<li>꼭 필요한 경우가 아니라면 검색 패턴 시작에 와일드카드를 사용하지 말자.
<u>와일드카드로 시작하는 검색 패턴은 처리가 가장 느리다.</u></li>
<li>와일드카드 기호의 위치 선정에 주의하자.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] image-rendering]]></title>
            <link>https://velog.io/@cl-song/CSS-image-rendering</link>
            <guid>https://velog.io/@cl-song/CSS-image-rendering</guid>
            <pubDate>Fri, 07 Oct 2022 05:38:35 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>MDN</strong>
image-rendering CSS 프로퍼티는 브라우저의 이미지 스케일링 방식에 대한 힌트를 제공합니다. 이 프로퍼티는 엘리먼트 자신에게 적용시킵니다. 스케일링(크기변경)이 안 된 이미지에게는 적용되지 않습니다.
&nbsp;
예를들어, 100x100 픽셀의 이미지가 있는데 페이지에서 요구하는 이미지는 200x200픽셀 (혹은 50x50px)이라면, 이미지는 새로운 면적만큼의 특정 알고리즘으로 인해 확대(혹은 축소)됩니다. 스케일링은 사용자의 상호작용(줌기능) 으로 인해 일어날겁니다.</p>
</blockquote>
<p><u>원본 이미지보다 이미지가 확대되거나 축소될 때이미지가 흐릿해진 경우</u> 이미지 랜더링 방식을 변경하여 좀 더 뚜렷하게 보여준다.</p>
<pre><code class="language-css">image-rendering: auto;
image-rendering: crisp-edges;
image-rendering: pixelated;

/* 사용 예시 */
div {
    background: url(chessboard.gif) no-repeat 50% 50%;
    image-rendering: -moz-crisp-edges;         /* Firefox */
    image-rendering:   -o-crisp-edges;         /* Opera */
    image-rendering: -webkit-optimize-contrast;/* Webkit (non-standard naming) */
    image-rendering: crisp-edges;
    -ms-interpolation-mode: nearest-neighbor;  /* IE (non-standard property) */
}</code></pre>
<p>참고
<a href="https://developer.mozilla.org/ko/docs/Web/CSS/image-rendering">https://developer.mozilla.org/ko/docs/Web/CSS/image-rendering</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 고급 데이터 필터링]]></title>
            <link>https://velog.io/@cl-song/SQL-%EA%B3%A0%EA%B8%89-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%84%ED%84%B0%EB%A7%81</link>
            <guid>https://velog.io/@cl-song/SQL-%EA%B3%A0%EA%B8%89-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%84%ED%84%B0%EB%A7%81</guid>
            <pubDate>Thu, 06 Oct 2022 05:28:42 GMT</pubDate>
            <description><![CDATA[<h2 id="where-절-조합하기">WHERE 절 조합하기</h2>
<ul>
<li>WHERE 절에는 AND나 OR를 사용하여 여러 개의 조건을 지정할 수 있으므로 다양한 필터링 제어가 가능하다.</li>
</ul>
<h3 id="and-연산자-사용하기">AND 연산자 사용하기</h3>
<pre><code class="language-sql">SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = &#39;DLL01&#39; AND prod_price &lt;= 4;
-- 지정된 조건을 모두 충족하는 행을 가져오도록 WHERE 절에서 사용하는 키워드</code></pre>
<h3 id="or-연산자-사용하기">OR 연산자 사용하기</h3>
<pre><code class="language-sql">SELECT prod_name, prod_price
FROM Products
WHERE vend_id = &#39;DLL01&#39; OR vend_id = &#39;BRS01&#39;;
-- 지정된 조건을 하나라도 만족하는 행을 가져오도록 WHERE 절에서 사용하는 키워드</code></pre>
<h3 id="우선순위-이해하기">우선순위 이해하기</h3>
<pre><code class="language-sql">SELECT prod_name, prod_price
FROM Products
WHERE prod_price &gt;= 10 AND (vend_id = &#39;DLL01&#39; OR vend_id = &#39;BRS01&#39;);
-- 괄호가 AND 나 OR 연산자보다 우선순위가 높기 때문에 괄호 안의 내용 먼저 필터링한다.
-- 괄호가 없는 경우 AND 연산자의 우선순위가 OR보다 높기 때문에 값이 다르게 나온다.
-- WHERE 절에서 AND와 OR 연산자를 같이 사용할 때는 괄호를 사용하여 연산자를 묶자.</code></pre>
<h3 id="in-연산자-사용하기">IN 연산자 사용하기</h3>
<pre><code class="language-sql">SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN (&#39;DLL01&#39;, &#39;BRS01&#39;)
ORDER BY prod_name;
-- WHERE 절에서 값의 목록을 지정하는 키워드
-- 각각의 값을 OR로 연달아 비교하는 것과 같은 효과를 준다.
-- IN 연산자는 조건의 범위를 지정할 때 사용되며, 괄호 안에는 조건이 나열된다.(콤마로 구분)</code></pre>
<p><strong>IN 연산자를 사용하는 이유</strong></p>
<ul>
<li>조건이 많을 때는 IN 연산자 문법이 OR 연산자 문법보다 깔끔하고 읽기 편한다.</li>
<li>AND나 OR 연산자와 함께 사용할 때 연산자의 우선순위를 관리하기 편하다.</li>
<li>IN 연산자는 OR 연산자가 목록을 처리하는 것보다 속도가 빠르다.</li>
<li>IN 연산자는 SELECT 문을 포함할 수 있다. =&gt; 동적인 WHERE 절을 만들 수 있다.</li>
</ul>
<h3 id="not-연산자-사용하기">NOT 연산자 사용하기</h3>
<pre><code class="language-sql">SELECT prod_name
FROM Products
WHERE NOT vend_id = &#39;DLL01&#39;
-- WHERE vend_id &lt;&gt; &#39;DLL01&#39;
ORDER BY prod_name;
-- WHERE 절에서 조건을 부정하기 위해 사용하는 키워드
-- NOT 키워드는 단독으로 사용할 수 없기에 필터링하려는 열 뒤가 아니라 앞에 적는다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 데이터 필터링(WHERE)]]></title>
            <link>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%84%ED%84%B0%EB%A7%81WHERE</link>
            <guid>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%84%ED%84%B0%EB%A7%81WHERE</guid>
            <pubDate>Thu, 06 Oct 2022 01:42:41 GMT</pubDate>
            <description><![CDATA[<h2 id="where">WHERE</h2>
<ul>
<li>SELECT 문에서는 WHERE 절로 검색 조건을 지정하여 데이터를 필터링할 수 있다.</li>
<li>WHERE 절은 테이블 이름(FROM 절) 바로 다음에 적는다.<pre><code class="language-sql">SELECT 열 이름
FROM 테이블 이름
WHERE 검색 조건;</code></pre>
</li>
</ul>
<p><strong>WHERE 절 연산자</strong></p>
<table>
<thead>
<tr>
<th align="center">연산자</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">=</td>
<td align="center">같다.</td>
</tr>
<tr>
<td align="center">&lt;&gt;</td>
<td align="center">같지 않다.</td>
</tr>
<tr>
<td align="center">!=</td>
<td align="center">같지 않다.</td>
</tr>
<tr>
<td align="center">&lt;</td>
<td align="center">~보다 작다.</td>
</tr>
<tr>
<td align="center">&lt;=</td>
<td align="center">~보다 작거나 같다.</td>
</tr>
<tr>
<td align="center">!&lt;</td>
<td align="center">~보다 작지 않다.</td>
</tr>
<tr>
<td align="center">&gt;</td>
<td align="center">~보다 크다.</td>
</tr>
<tr>
<td align="center">&gt;=</td>
<td align="center">~보다 크거나 같다.</td>
</tr>
<tr>
<td align="center">!&gt;</td>
<td align="center">~보다 크지 않다.</td>
</tr>
<tr>
<td align="center">BETWEEN</td>
<td align="center">두 개의 특정한 값 사이</td>
</tr>
<tr>
<td align="center">IS NULL</td>
<td align="center">값이 NULL이다.</td>
</tr>
</tbody></table>
<h3 id="하나의-값으로-확인하기">하나의 값으로 확인하기</h3>
<pre><code class="language-sql">SELECT prod_name, prod_price
FROM Products
WHERE prod_price = 3.49;

SELECT prod_name, prod_price
FROM Products
WHERE prod_price &lt;= 10
ORDER BY prod_price DESC;</code></pre>
<h3 id="일치하지-않는-값-확인하기">일치하지 않는 값 확인하기</h3>
<pre><code class="language-sql">SELECT vend_id, prod_name
FROM Products
WHERE vend_id != &#39;DLL01&#39;;
-- WHERE vend_id &lt;&gt; &#39;DLL01&#39;;</code></pre>
<h3 id="특정-범위의-값-확인하기">특정 범위의 값 확인하기</h3>
<pre><code class="language-sql">SELECT prod_name, prod_price
FROM Products
WHERE prod_price BETWEEN 5 AND 10;</code></pre>
<h3 id="값이-없는-데이터-확인하기">값이 없는 데이터 확인하기</h3>
<pre><code class="language-sql">SELECT prod_name
FROM Products
WHERE prod_price IS NULL;
-- 열이 아무런 값도 가지고 있지 않을 때, 열이 NULL 값을 가지고 있다고 한다.
-- 위의 명령문은 prod_price의 값이 0이라는 의마가 아니라 prod_price열에서 비어있는 제품을 검색하라는 의미이다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 가져온 데이터 정렬하기(ORDER BY)]]></title>
            <link>https://velog.io/@cl-song/SQL-%EA%B0%80%EC%A0%B8%EC%98%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0ORDER-BY</link>
            <guid>https://velog.io/@cl-song/SQL-%EA%B0%80%EC%A0%B8%EC%98%A8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0ORDER-BY</guid>
            <pubDate>Wed, 05 Oct 2022 08:16:00 GMT</pubDate>
            <description><![CDATA[<h2 id="order-by">ORDER BY</h2>
<ul>
<li>SELECT 문으로 가져온 데이터를 정렬할 때, ORDER BY 절을 사용한다.</li>
<li>SELECT 문의 가장 마지막에 와야 한다.</li>
<li>SELECT 절에서 가져온 열로 정렬하지 않아도 된다.</li>
</ul>
<h3 id="데이터-정렬하기">데이터 정렬하기</h3>
<pre><code class="language-sql">SELECT 열 이름
FROM 테이블 이름
ORDER BY 열 이름;</code></pre>
<h3 id="여러-개의-열-정렬하기">여러 개의 열 정렬하기</h3>
<pre><code class="language-sql">SELECT 열 이름1, 열 이름2
FROM 테이블 이름
ORDER BY 열 이름1, 열 이름2;
-- 여러 열로 정렬할 때의 순서는 적은 순서 그대로이다.
-- 열 이름 1이 같을 때 열 이름 2로 정렬된다.</code></pre>
<h3 id="열의-위치로-정렬하기">열의 위치로 정렬하기</h3>
<pre><code class="language-sql">SELECT 열 이름1, 열 이름2, 열 이름3
FROM 테이블 이름
ORDER BY 1, 2;
-- ORDER BY는 SELECT 절에 나열된 열의 상대적 위치로도 정렬이 가능하다.
-- 위의 경우에는 열 이름 1로 정렬하고, 열 이름 1이 같을 때 열 이름 2로 정렬된다.</code></pre>
<h3 id="내림차순-정렬하기">내림차순 정렬하기</h3>
<pre><code class="language-sql">SELECT 열 이름1, 열 이름2
FROM 테이블 이름
ORDER BY 열 이름 DESC;
-- DESC는 DESCENDING의 준말로 이 키워드는 명시된 열에만 적용된다.
-- 여러 열을 내림차순으로 정렬하려면, 각각의 열에 DESC키워드를 모두 적어야 한다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 데이터 가져오기(SELECT 문)]]></title>
            <link>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/SQL-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0</guid>
            <pubDate>Wed, 05 Oct 2022 02:11:32 GMT</pubDate>
            <description><![CDATA[<h2 id="select-문">SELECT 문</h2>
<ul>
<li>SELECT 문은 테이블에서 정보를 가져오기 위해 사용하며 <code>무엇을 가져올지, 어디에서 가져올지 명시</code>해야 한다.</li>
<li>SQL 문은 대소문자를 구문하지 않는다.</li>
<li>SQL 문에서 추가로 사용된 공백문자는 모두 무시된다.</li>
</ul>
<h3 id="하나의-열-가져오기">하나의 열 가져오기</h3>
<pre><code class="language-sql">SELECT 열 이름
FROM 테이블 이름;</code></pre>
<h3 id="여러-개의-열-가져오기">여러 개의 열 가져오기</h3>
<pre><code class="language-sql">SELECT 열 이름1, 열 이름2 
FROM 테이블 이름;</code></pre>
<h3 id="모든-열-가져오기">모든 열 가져오기</h3>
<pre><code class="language-sql">SELECT *
FROM 테이블 이름;</code></pre>
<h3 id="행의-중복-출력-방지하기">행의 중복 출력 방지하기</h3>
<pre><code class="language-sql">SELECT DISTINCT 열 이름
FROM 테이블 이름;
-- DISTINCT 키워드는 부분적으로 적용할 수 없다.
-- 열 이름을 두 개 적은 경우, 두 항목을 결합해 고유한 조합을 반환한다.</code></pre>
<h3 id="결과-제한하기">결과 제한하기</h3>
<pre><code class="language-sql">-- _Microsoft SQL Server_
SELECT TOP 5 열 이름
FROM 테이블 이름;

-- _Db2_
SELECT 열 이름
FROM 테이블 이름
FETCH FIRST 5 ROWS ONLY;

-- _Oracle_
SELECT 열 이름
FROM 테이블 이름
WHERE ROWNUM &lt;= 5;

-- _MySQL, MariaDB, PostgreSQL, SQLite_
SELECT 열 이름
FROM 테이블 이름
LIMIT 5; -- 5 개의 행을 가져오기
LIMIT 5 OFFSET 5; -- 5개의 행부터 5개의 행을 가져오기(**0번째 행부터 시작**)
LIMIT 5, 5 -- 줄여쓰기 가능하나 순서가 반대로 되므로 주의(OFFSET값, LIMIT값)</code></pre>
<h3 id="주석"><strong>주석</strong></h3>
<pre><code class="language-sql"># 이 문장 주석
\* 여러행 주석
  여러 행 주석 */
SELECT 열 이름 -- 하이픈 뒤 주석
FROM 테이블 이름;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] SQL 이해하기]]></title>
            <link>https://velog.io/@cl-song/SQL-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/SQL-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 04 Oct 2022 05:53:46 GMT</pubDate>
            <description><![CDATA[<h2 id="데이터베이스database">데이터베이스(Database)</h2>
<ul>
<li>데이터를 저장하는 공간</li>
<li>정리된 데이터를 저장하기 위한 그릇(하나 또는 여러 개의 파일)</li>
</ul>
<blockquote>
<p>데이터베이스 소프트웨어는 데이터베이스 관리 시스템(DBMS: DataBase Management System)이라 부르고, 데이터베이스는 이 DBMS를 생성하고 조작하는 물리적인 저장공간을 말한다.
<strong>즉 데이터베이스와 소통하기 위해 고안된 언어가 SQL이다.</strong></p>
</blockquote>
<h2 id="테이블">테이블</h2>
<ul>
<li>특정한 형태의 데이터로 이루어진 구조화된 목록</li>
<li>모든 테이블은 다른 테이블과 구별되는 고유한 이름을 가진다.(같은 데이터베이스에는 같은 이름의 테이블이 존재할 수 없다.)</li>
<li>테이블은 데이터를 어떤 형태로 저장할지, 어떻게 쪼개 저장할지 등을 정의하는 여러 데이터 구조와 속성으로 이루어져 있다. 
=&gt; 이런 정보의 집합을 <strong>스키마</strong>라고 한다.</li>
<li>테이블은 <strong>열(Column)</strong>로 구성된다. 각각의 열은 데이터형(Datatype)을 가지고 있다. 
=&gt; 데이터형은 열에 저장할 수 있는 데이터의 유형을 정의한다. 
=&gt; 데이터를 바르게 정렬하고 디스크 사용량을 최적화하는 역할</li>
<li>테이블에 있는 데이터는 <strong>행(Row)</strong>에 담긴다.</li>
</ul>
<blockquote>
<p>ex) 엑셀 테이블의 세로가 테이블 열이고, 가로가 테이블 행이다. 
고객 테이블의 한 행에는 한 명의 고객 정보를 저장한다. 테이블에 있는 행의 개수는 그 안에 들어 있는 레코드의 수이다.</p>
</blockquote>
<ul>
<li>테이블의 각 행을 구별해주는 열(또는 열 집합)을 <strong>기본 키(Primary Key)</strong>라고 한다.
=&gt; 기본 키는 특정 행을 참조하기 위해 사용된다. </li>
</ul>
<blockquote>
<p>기본 키의 조건</p>
</blockquote>
<ul>
<li>행이 같은 기본 키 값을 가질 수 없다.</li>
<li>모든 행은 기본 키 값을 가져야 한다.(기본 키 열은 NULL 값을 허용 X)</li>
<li>기본 키 열에 있는 값은 변경하거나 업데이트할 수 없다.</li>
<li>기본 키 값은 재사용할 수 없다.(테이블의 어떤 행을 삭제할 경우 기본 키도 같이 삭제되지만 다른 행에 다시 할당 X)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SEO] 검색 엔진 최적화 정리]]></title>
            <link>https://velog.io/@cl-song/SEO</link>
            <guid>https://velog.io/@cl-song/SEO</guid>
            <pubDate>Fri, 30 Sep 2022 06:22:26 GMT</pubDate>
            <description><![CDATA[<p>SEO(Search Engine Optimization)약자로, <strong>검색 엔진 최적화</strong>를 뜻한다.</p>
<h2 id="google-검색-결과-화면">Google 검색 결과 화면</h2>
<p><img src="https://velog.velcdn.com/images/cl-song/post/3a218cd7-0815-4444-a862-3f16cf4e50ea/image.png" alt="설명">
Google에서 &#39;고객센터&#39;로 검색 시 나오는 화면으로 알 수 있는 정보는 다음과 같다.</p>
<ol>
<li>검색 결과</li>
<li>사이트링크(네이버에서는 서브링크)
사이트링크는 자동화되어있어 따로 설정할 수 없으나 권장되는 사항은 아래와 같다.<ul>
<li>페이지 제목과 머리글에 사용하는 텍스트는 올바르고 유익하고 관련성이 있으며 간결해야 합니다.</li>
<li>사용자가 탐색하기 쉬운 논리적 사이트 구조를 만들고 다른 관련 페이지에서 중요한 페이지로 연결되도록 합니다.</li>
<li>내부 링크의 앵커 텍스트는 간결하고 링크가 가리키는 페이지와 관련이 있어야 합니다.</li>
<li>콘텐츠에서 반복을 피하세요.<br>
## 검색 결과 관련 메타태그

</li>
</ul>
</li>
</ol>
<pre><code class="language-html">&lt;title&gt;페이지 타이틀&lt;/title&gt;
&lt;meta charset=&quot;utf-8&quot;&gt;

&lt;!-- 검색엔진의 크롤링 및 색인 생성 동작을 제어 --&gt;
&lt;!-- 검색 결과에 표시 할 것인지, 링크를 이동하게 할 것인지 지정 --&gt;
&lt;!-- [all], [index or noindex, follow or nofollow] --&gt;
&lt;meta name=&quot;robots&quot; content=&quot;all&quot;&gt; 

&lt;!-- 뷰포트 설정, 반응형 웹 --&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, user-scalable=no, initial-scale=1.0&quot;&gt;

&lt;!-- 사이트에 관련된 키워드, 과거에는 키워드로 검색결과를 보여주주었으나 현재는 사용되지 않음 --&gt;
&lt;meta name=&quot;Keywords&quot; content=&quot;키워드1, 키워드2, 키워드3&quot;&gt;

&lt;!-- 사이트에 관련된 설명, 검색 결과 시 보여짐--&gt;
&lt;meta name=&quot;description&quot; content=&quot;사이트에 관련된 설명&quot;&gt;

&lt;!-- 사이트 저자 정의 --&gt;
&lt;meta name=&quot;author&quot; content=&quot;저자&quot;&gt;</code></pre>
<p>그 외 <strong>canonical태그</strong></p>
<pre><code class="language-html">&lt;!-- 중복 URL 또는 비슷한 페이지에 대해 표준 URL을 지정. 절대경로로 사용 --&gt;
&lt;link rel=&quot;canonical&quot; href=&quot;https://xxxxx.xxx&quot; /&gt;</code></pre>
<blockquote>
<p>Google에서는 <a href="https://search.google.com/search-console/about">Search Console</a> 도구를 이용하여 검색 결과 인지도를 모니터링할 수 있는 서비스를 제공한다.</p>
</blockquote>
<p>참고
<a href="https://developers.google.com/search/docs?hl=ko">https://developers.google.com/search/docs?hl=ko</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[algorithm] 10부제]]></title>
            <link>https://velog.io/@cl-song/algorithm-10%EB%B6%80%EC%A0%9C</link>
            <guid>https://velog.io/@cl-song/algorithm-10%EB%B6%80%EC%A0%9C</guid>
            <pubDate>Thu, 18 Aug 2022 05:52:11 GMT</pubDate>
            <description><![CDATA[<p><strong>10부제</strong>
서울시는 6월 1일부터 교통 혼잡을 막기 위해서 자동차 10부제를 시행한다. 
자동차 10부제는 자동차 번호의 일의 자리 숫자와 날짜의 일의 자리 숫자가 일치하면 해당 자동차의 운행을 금지하는 것이다. </p>
<p>예를 들어, 자동차 번호의 일의 자리 숫자가 7이면 7일, 17일, 27일에 운행하지 못한다. 
또한, 자동차 번호의 일의 자리 숫자가 0이면 10일, 20일, 30일에 운행하지 못한다.</p>
<p>여러분들은 일일 경찰관이 되어 10부제를 위반하는 자동차의 대수를 세는 봉사활동을 하려고 한다. 
날짜의 일의 자리 숫자가 주어지고 7대의 자동차 번호의 끝 두 자리 수가 주어졌을 때 위반하는 자동차의 대수를 출력하는 프로그램을 작성하세요.</p>
<ul>
<li><p>입력설명
첫 줄에는 날짜의 일의 자리 숫자가 주어지고 두 번째 줄에는 7대의 자동차 번호의 끝 두 자리 숫자가 주어진다.</p>
</li>
<li><p>출력설명
주어진 날짜와 자동차의 일의 자리 숫자를 보고 10부제를 위반하는 차량의 대수를 출력합니다.</p>
</li>
<li><p>입력예제 1
3
25 23 11 47 53 17 33</p>
</li>
<li><p>출력예제 1
3</p>
</li>
<li><p>입력예제 2
0
12 20 54 30 87 91 30</p>
</li>
<li><p>출력예제 2
3</p>
</li>
</ul>
<p>출처: 한국정보올림피아드</p>
<blockquote>
<p><strong>TIP</strong>
어떤 숫자든 10으로 나누면 일의자리 앞의 숫자가 몫이되고 일의자리 숫자는 나머지가 된다.</p>
</blockquote>
<pre><code class="language-javascript">function solution(day, arr) {
  let answer = 0;

  for(let x of arr) {
    if( x % 10 === day) answer++;
  }

  return answer;
}

let arr = [25, 23, 11, 47, 53, 17, 33];
console.log(solution(3, arr));</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[algorithm] 홀수]]></title>
            <link>https://velog.io/@cl-song/algorithm-%ED%99%80%EC%88%98</link>
            <guid>https://velog.io/@cl-song/algorithm-%ED%99%80%EC%88%98</guid>
            <pubDate>Thu, 18 Aug 2022 05:48:05 GMT</pubDate>
            <description><![CDATA[<p><strong>홀수</strong>
7개의 자연수가 주어질 때, 이들 중 홀수인 자연수들을 모두 골라 그 합을 구하고, 
고른 홀수들 중 최소값을 찾는 프로그램을 작성하세요.</p>
<p>예를 들어, 7개의 자연수 12, 77, 38, 41, 53, 92, 85가 주어지면
이들 중 홀수는 77, 41, 53, 85이므로 그 합은77 + 41 + 53 + 85 = 256이 되고,
41 &lt; 53 &lt; 77 &lt; 85이므로 홀수들 중 최소값은 41이 된다</p>
<ul>
<li><p>입력설명
첫 번째 줄에 자연수 7개가 주어진다. 주어지는 자연수는 100보다 작다. 
홀수가 한 개 이상 반드시 존재한다</p>
</li>
<li><p>출력설명
첫째 줄에 홀수들의 합을 출력하고, 둘째 줄에 홀수들 중 최소값을 출력한다.</p>
</li>
<li><p>입력예제 1
12 77 38 41 53 92 85</p>
</li>
<li><p>출력예제 1
256
41</p>
</li>
</ul>
<p>출처: 한국정보올림피아드</p>
<pre><code class="language-javascript">// 풀이1
function solution(arr) {
  let answer = [];
  let oddArr = [];
  let oddSum = 0;

  for(let i = 0; i &lt; arr.length; i++) {
    if( arr[i] % 2 === 1 ) {
      oddArr.push(arr[i]);
      oddSum += arr[i];
    }
  }
  answer.push(oddSum);
  answer.push(Math.min(...oddArr));

  return answer;
}</code></pre>
<pre><code class="language-javascript">// 풀이2
function solution(arr) {
  let answer = [];
  let sum = 0, min = Number.MAX_SAFE_INTEGER;

  for(let x of arr) {
    if( x % 2 === 1 ) {
      sum += x;
      if(x &lt; min) min = x;
    }
  }
  answer.push(sum);
  answer.push(min);

  return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[algorithm] 최솟값 구하기]]></title>
            <link>https://velog.io/@cl-song/algorithm-%EC%B5%9C%EC%86%9F%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/algorithm-%EC%B5%9C%EC%86%9F%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 16 Aug 2022 08:16:25 GMT</pubDate>
            <description><![CDATA[<p><strong>최솟값 구하기</strong>
7개의 수가 주어지면 그 숫자 중 가장 작은 수를 출력하는 프로그램을 작성하세요.</p>
<ul>
<li><p>입력설명
첫 번째 줄에 7개의 수가 주어진다.</p>
</li>
<li><p>출력설명
첫 번째 줄에 가장 작은 값을 출력한다.</p>
</li>
<li><p>입력예제 1
5 3 7 11 2 15 17</p>
</li>
<li><p>출력예제 1
2</p>
</li>
</ul>
<blockquote>
<p><strong>TIP</strong></p>
</blockquote>
<ul>
<li>Number.MAX_SAFE_INTEGER
안전한 최대 정수값을 나타내며 최소값을 구하는 문제를 풀때 초기화 역할로 사용</li>
<li>Number.MIN_SAFE_INTEGER
안전한 최소 정수값을 나타내며 최대값을 구하는 문제를 풀때 초기화 역할로 사용</li>
<li>Math.max([value1[, value2[, ...]]])
주어진 숫자들 중 가장 큰 값을 반환</li>
<li>Math.min([value1[, value2[, ...]]])
주어진 숫자들 중 가장 작은 값을 반환</li>
</ul>
<pre><code class="language-javascript">// 풀이1
function solution(arr) {
  let answer;
  answer = arr[0];
  for(let i = 1; i &lt; arr.length; i++) {
    if(arr[i] &lt; answer) {
      answer = arr[i];
    }
  }

  return answer;
}</code></pre>
<pre><code class="language-javascript">// 풀이2
function solution(arr) {
  let answer, min = Number.MAX_SAFE_INTEGER; // min값을 큰 숫자로 미리 초기화시켜둔다.
  for(let i = 0; i &lt; arr.length; i++) {
    if(arr[i] &lt; min) min = arr[i];
  }
  answer = min;
  return answer;
}</code></pre>
<pre><code class="language-javascript">// 풀이3. 내장함수 사용
function solution(arr) {
    let answer = Math.min(...arr); // ...전개연산자를 사용해 배열을 펼쳐 인자로 넣어준다.
    return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[algorithm] 1부터 N까지 합 출력하기]]></title>
            <link>https://velog.io/@cl-song/algorithm-1%EB%B6%80%ED%84%B0-N%EA%B9%8C%EC%A7%80-%ED%95%A9-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cl-song/algorithm-1%EB%B6%80%ED%84%B0-N%EA%B9%8C%EC%A7%80-%ED%95%A9-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 16 Aug 2022 07:51:05 GMT</pubDate>
            <description><![CDATA[<p><strong>1부터 N까지 합 출력하기</strong>
자연수 N이 입력되면 1부터 N까지의 합을 출력하는 프로그램을 작성하세요.</p>
<ul>
<li><p>입력설명
첫 번째 줄에 20이하의 자연수 N이 입력된다.</p>
</li>
<li><p>출력설명
첫 번째 줄에 1부터 N까지의 합을 출력한다.</p>
</li>
<li><p>입력예제 1
6</p>
</li>
<li><p>출력예제 1
21</p>
</li>
<li><p>입력예제 2
10</p>
</li>
<li><p>출력예제 2
55</p>
</li>
</ul>
<pre><code class="language-javascript">function solution(n) {
  let answer = 0;
  for(let i = 1; i &lt;= n; i++) {
    answer = answer + i;
  }

  return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[algorithm] 연필개수]]></title>
            <link>https://velog.io/@cl-song/algorithm-%EC%97%B0%ED%95%84%EA%B0%9C%EC%88%98</link>
            <guid>https://velog.io/@cl-song/algorithm-%EC%97%B0%ED%95%84%EA%B0%9C%EC%88%98</guid>
            <pubDate>Tue, 16 Aug 2022 07:07:30 GMT</pubDate>
            <description><![CDATA[<p>** 연필개수**
연필 1다스는 12자루입니다. 학생 1인당 연필을 1자루씩 나누어 준다고 할 때, N명의 학생수를 입력하면 필요한 연필의 다스 수를 계산하는 프로그램을 작성하세요.</p>
<ul>
<li><p>입력설명
첫 번째 줄에 1000이하의 서로 자연수 N이 입력된다.</p>
</li>
<li><p>출력설명
첫 번째 줄에 필요한 다스 수를 출력합니다.</p>
</li>
<li><p>입력예제 1
25</p>
</li>
<li><p>출력예제 1
3</p>
</li>
<li><p>입력예제 2
178</p>
</li>
<li><p>출력예제 2
15</p>
</li>
</ul>
<blockquote>
<p><strong>TIP</strong>
Math.floor() 함수: 가장 가까운 정수로 내림
Math.ceil() 함수: 가장 가까운 정수로 올림
Math.round() 함수: 반올림</p>
</blockquote>
<pre><code class="language-javascript">function solution(n) {
  let answer;
  answer = Math.ceil(n / 12);
  return answer;
}</code></pre>
]]></description>
        </item>
    </channel>
</rss>