{"componentChunkName":"component---src-templates-blog-post-js","path":"/Database/2020-04-13-데이터베이스-조인연산/","result":{"data":{"site":{"siteMetadata":{"title":"Hun's Footsteps 🥷","author":"전여훈","siteUrl":"https://jeonyeohun.netlify.app","comment":{"disqusShortName":"","utterances":"jeonyeohun/jeonyeohun.github.io"},"sponsor":{"buyMeACoffeeId":"jeonyeohun"}}},"markdownRemark":{"id":"2ca6be2d-b593-59ee-b790-2ccbd999f3cb","excerpt":"Join 조인은 다수의 테이블을 연결해서 데이터를 뽑아내는 연산을 의미한다. 기본적으로 Join 은 normalized 된 테이블을 사용하게 된다. Join에는 여러 종류가 있는데, 하나씩 살펴보자. Natural Join Natural 은 두 테이블에서 같은 attribute를 기준으로 테이블을 합쳐서 새로운 테이블을 만드는 것을 의미한다. 그리고 중복되는 attribute 는 합쳐서 하나로 만든다. students_info student_id student_name age sex 1 여훈 2…","html":"<h1 id=\"join\" style=\"position:relative;\"><a href=\"#join\" aria-label=\"join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Join</h1>\n<p>조인은 다수의 테이블을 연결해서 데이터를 뽑아내는 연산을 의미한다. 기본적으로 Join 은 normalized 된 테이블을 사용하게 된다. Join에는 여러 종류가 있는데, 하나씩 살펴보자.</p>\n<h2 id=\"natural-join\" style=\"position:relative;\"><a href=\"#natural-join\" aria-label=\"natural join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Natural Join</h2>\n<p>Natural 은 두 테이블에서 같은 attribute를 기준으로 테이블을 합쳐서 새로운 테이블을 만드는 것을 의미한다. 그리고 중복되는 attribute 는 합쳐서 하나로 만든다.</p>\n<p>students_info</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n</tr>\n</tbody>\n</table>\n<p>students_department</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">CSEE</td>\n</tr>\n</tbody>\n</table>\n<p>위와 같은 두 테이블이 있다면, Natural Join을 했을 때, Student<em>id 를 기준으로 합쳐져서 다음과 같은 테이블이 만들어진다. 두 테이블에서 Student</em>id 가 각각 존재하지만 Join 이후에는 하나가 된 것을 볼 수 있다.</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n<td align=\"center\">CSEE</td>\n</tr>\n</tbody>\n</table>\n<p>SQL 에서 Natural Join 을 할때는 다음과 같은 문법으로 할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> <span class=\"token operator\">*</span>\n<span class=\"token keyword\">FROM</span> students_info<span class=\"token punctuation\">,</span> students_department\n<span class=\"token keyword\">WHERE</span> students_info<span class=\"token punctuation\">.</span>student_id <span class=\"token operator\">=</span> student_department<span class=\"token punctuation\">.</span>student_id</code></pre></div>\n<p>or</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> <span class=\"token operator\">*</span>\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">JOIN</span> students_department</code></pre></div>\n<p>처음 쿼리는 Natural Join을 직접적으로 사용하지는 않았지만, WHERE 문을 통해서 student_id 가 같은 tuple을 뽑기로 했기 때문에 아래 쿼리에서 직접적으로 NATURAL JOIN 을 사용한 것과 동일한 결과가 나온다.</p>\n<p>그런데 Natural Join은 사용자가 지정하지 않고 연산과정에서 동일한 attribute name 을 찾아서 join 하기 때문에 attribute 이름만 같고 그 의미가 다른 테이블들이 합쳐지면서 정보가 훼손 될 가능성이 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> name<span class=\"token punctuation\">,</span> title\n<span class=\"token keyword\">FROM</span> student<span class=\"token punctuation\">,</span> <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">JOIN</span> takes <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">JOIN</span> course</code></pre></div>\n<p>이런 쿼리를 사용했다고 하자, 한번에 세 테이블을 합치게 되는데 문제는 세 테이블이 가진 동일한 attribute의 의미가 달라지는 경우가 생겨버린다.</p>\n<h2 id=\"join-inner-join\" style=\"position:relative;\"><a href=\"#join-inner-join\" aria-label=\"join inner join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Join (Inner Join)</h2>\n<p>Natural Join의 문제를 해결하기 위해서 Join 연산을 사용할 수 있다. Natural Join은 ON 연산의 사용을 허용한다. Where 처럼 ON 을 통해서 테이블을 합칠 조건을 명시해줄 수 있다.</p>\n<p>students_info</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n</tr>\n</tbody>\n</table>\n<p>students_department</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">CSEE</td>\n</tr>\n</tbody>\n</table>\n<p>앞서 사용했던 테이블을 Natural Join을 통해서 합칠 때는</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> <span class=\"token operator\">*</span>\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">JOIN</span> students_department</code></pre></div>\n<p>이런 쿼리를 사용했다. 우리는 쿼리를 통해서 어떤 attribute가 같은 이름을 가지는지 명시하지 않았지만, Natural Join이 해당 attribute를 알아서 찾고 합쳐주었다.</p>\n<p>Join 을 사용하게 되면</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> <span class=\"token operator\">*</span>\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">JOIN</span> students_department\n<span class=\"token keyword\">ON</span> tudents_info<span class=\"token punctuation\">.</span>student_id <span class=\"token operator\">=</span> student_department<span class=\"token punctuation\">.</span>student_id</code></pre></div>\n<p>이렇게 어떤 attribute 를 기준으로 합칠건지 지정해줄 수가 있다. 따라서, 중복되는 컬럼이 여러개 있을 때, 어떤 컬럼을 기준으로 합칠지 사용자가 선택해줄 수 있다.</p>\n<p>만약, 두 테이블에 값이 일치하지 않는 tuple들이 있다면 어떻게 될까? 당연하게도 그런 tuple들은 새로 합쳐져서 만들어지는 테이블에서는 제외된다.</p>\n<h2 id=\"outer-join\" style=\"position:relative;\"><a href=\"#outer-join\" aria-label=\"outer join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Outer Join</h2>\n<p>Natural Join 과 Inner Join은 두 테이블에서 일치하는 값이 없는 tuple들을 모두 없애버리게 되는데, 어떤 경우에는 해당 정보들이 필요할지도 모른다.</p>\n<p>Outer Join 은 Inner Join 이나 Natural Join 과는 다르게 짝을 찾지 못한 attribute도 결과 테이블에 유지한다. 그리고 Outer Join의 종류에 따라서 짝을 찾지 못한 tuple들 중 어떤 종류의 tuple들만 남길지 선택할 수 있다. 짝을 찾지 못하게 되면 합쳐져서 새로 추가된 attribute에 넣어줄 값이 존재하지 않기 때문에, 해당 attribute의 값을 null로 초기화 해준다.</p>\n<h3 id=\"left-outer-join\" style=\"position:relative;\"><a href=\"#left-outer-join\" aria-label=\"left outer join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Left Outer Join</h3>\n<p>Left Outer Join은 말 그대로 왼쪽은 모두 포함하는 조인의 형태이다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 560px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 85%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACMklEQVQ4y41UW08aQRTe/18NsWqLIrFpH3xsfGj60IKLF1BYVwvYCIjL7oohwJLQ7oVlu/N1ZmBwBzDtSU7OXM58853LjIK5EEK4zsYx4jhezNlYzJkm94QVoiQnswP4byFrnJXlzWk4wY9qDYVCAbqu41qroHR5hWKxiH5/AF3TUCyVMBqN1jMUYYiNMAxRv/uJ+0YDlmWj2WygXNFQq1UxGAxxV6/x/fF4LKVKnFdeywVoHkEiaSmKIpo/IvkmzzNVkotxFOKq3sHRmYmDvIVPpyZObgw4wwG6TzY6HZOytmCaJgzDkFgKu2AYBj6O1BY2TjzsloH3GvCuAqTOI6SO63g0TIntdDrloMPhUAJVZpbgy+UDNs8iZG+AvXJMlXB7cA3s0As+qgaiMACZt5GQdruNIAheGLKB44zw9nsP+zqQZmCU2V6FcJumwBkKmlJd1Fv2vC9f8ui6LmzblgGZ4/Z5gH0NnBkDEWACcLMQIH87O/gnAcjYrQBWm9Y/ATdUH7k1gL7vrwL2aX9t5fpyyOWlkAsebhvWSsgMkFU+UWXugs8XD0hdxMjqclEyrNoUMJvvYOK7i7cthFWa5XGlbdzfv/AhRyt9GvKWSc91qwS8Ob5H69FcecesH3u9ntw2/Mb5ZOJ7UGkjH6oWdr/ZyORtfK100O0+47n7RAEsni+mjJnjOK83dpx4TtOJz3MzCTyeDiFsjanneYuwl5+hIv+DRAKeXQTp/1v3fSUx/gKEmgAId/mZ9QAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"1\"\n        title=\"1\"\n        src=\"/static/29b9b73fdcdb02ec3deac6c268a0a5d3/b06ae/leftouterjoin.png\"\n        srcset=\"/static/29b9b73fdcdb02ec3deac6c268a0a5d3/5a46d/leftouterjoin.png 300w,\n/static/29b9b73fdcdb02ec3deac6c268a0a5d3/b06ae/leftouterjoin.png 560w\"\n        sizes=\"(max-width: 560px) 100vw, 560px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>students_info</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">국인</td>\n<td align=\"center\">22</td>\n<td align=\"center\">M</td>\n</tr>\n</tbody>\n</table>\n<p>students_department</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">SWFL</td>\n</tr>\n</tbody>\n</table>\n<p>지금 보니까 예시 테이블이 별로 좋은 것 같지는 않다.. 어쩃든 Left Outer Join을 시행해보자. 위 테이블은 보면 이유는 모르겠지만 국인이의 정보가 department 테이블에 없고, id 5번의 정보가 student 테이블에 없다. Inner Join 과 Natural Join 을 사용했다면, 국인이와 id 5번 학생의 정보가 사라졌겠지만, 이번엔 그렇지 않다. Left Outer Join 이기 때문에 왼쪽에 기준으로 테이블을 합쳐보자.</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">국인</td>\n<td align=\"center\">22</td>\n<td align=\"center\">M</td>\n<td align=\"center\">null</td>\n</tr>\n</tbody>\n</table>\n<p>Join 을 때릴(?) 서로 공유되는 attribute 는 student_id 이다. 하지만 왼쪽 테이블에 있는 국인이에 대한 정보가 오른쪽 테이블에는 존재하지 않는다. Left Outer Join 은 이때 왼쪽에만 존재하는 정보를 살리고 합쳤을 때 비어있게 되는 attribute 에 null을 삽입해준다.</p>\n<p>따라서 왼쪽 테이블을 기준으로 합쳤을 때 추가되는 Department 에 국인이에 대한 값이 null이 들어가게 되는 것이다.</p>\n<p>쿼리문은 다음과 같이 작성하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> <span class=\"token operator\">*</span>\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">LEFT</span> <span class=\"token keyword\">OUTER</span> <span class=\"token keyword\">JOIN</span> students_department</code></pre></div>\n<h3 id=\"right-outer-join\" style=\"position:relative;\"><a href=\"#right-outer-join\" aria-label=\"right outer join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Right Outer Join</h3>\n<p>Right Outer Join 은 Left Outer Join 과는 반대로 오른쪽 테이블에 있는 정보를 모두 살리는 것이다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 560px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 85%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACTUlEQVQ4y5WT7W/SUBTG+fNNjNucOjfYvpLIYvxgjMCg4lwW1sFGXAxmC/aWMkYprx3Q9z7ee2mhLXzQk5zccsn5nee83BQi5vs+/teSMankH+x0HId/s5O567r418QbQNM0cXqaQy6XQ+WbgOqViIogoFgsoZD/CqXzCKFcRj5fgKqqGwlS4UXonudB13U0m01Mp1PMZjNomkZBHaj9PiyacKD1MRqNaHILyfhUtNTQbNuGYRgcyBSva3UwmugYjnW4joVt7UpFL1ivZFmGJEno9XpcmSy30SYtiHctnAgEe2cq9soaDs5klOt/YJtGDBpT2Gq1MJlMNhpdqP7Gi8IQ7+vAEfPa8nx1biFbeYBjraErYLfbxWAw4N+sjy51Zg/kETulIY4bFCJ6OBR97uz75JZCv5uo3ErLuLDksNTYcHgeF59FGa8vfWRqAeiawdgZJKBqM0IblrFYT3k+n0NRlJW6ULVjzpG9UHBQWwYzyOEKFiSgpe/kO3ieR4CLxWIFDBVyuG3gw6WCdyKWygJgCD1kSShwv6hgRkXFhkII4esSQr1lzag0CG2+ieN6BBacaZrkLU2WPSfwXSsOHI/HvI+hecFQnvUp0kKHl82g6aCHGfo7fQO8LPZxT7pBTGIP2e4xpWyp11vrod64w/6Xe+xSpW+uwFuw+8OmO/mE618kmDC2vxT2OphS1tMOdUkimE7GXOnFTxmfqgo+Ui/dEDypWhC7ZbGTz489OTasDXNNOqz1vRcZYuzpRS+TSUJ3aV3+qsc+hyUV/gUuKf+P4iqPjgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"rightouterjoin\"\n        title=\"rightouterjoin\"\n        src=\"/static/3e7f62b6af07e6a670c2764a74dd101e/b06ae/rightouterjoin.png\"\n        srcset=\"/static/3e7f62b6af07e6a670c2764a74dd101e/5a46d/rightouterjoin.png 300w,\n/static/3e7f62b6af07e6a670c2764a74dd101e/b06ae/rightouterjoin.png 560w\"\n        sizes=\"(max-width: 560px) 100vw, 560px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Left Outer Join 에서 사용한 것과 동일한 테이블은 Right Outer Join으로 합쳐보자</p>\n<p>students_info</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">국인</td>\n<td align=\"center\">22</td>\n<td align=\"center\">M</td>\n</tr>\n</tbody>\n</table>\n<p>students_department</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">SWFL</td>\n</tr>\n</tbody>\n</table>\n<p>위 두 테이블을 오른쪽을 기준으로 합치면,</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">Department</th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">CSEE</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">CPSW</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">CSEE</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">SWFL</td>\n<td align=\"center\">null</td>\n<td align=\"center\">null</td>\n<td align=\"center\">null</td>\n</tr>\n</tbody>\n</table>\n<p>이렇게 국인이의 정보는 포함하지 않지만 오른쪽 테이블에 있던 id 5번의 정보는 포함한 채로 합쳐진다.</p>\n<p>쿼리문은 다음과 같이 작성할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> <span class=\"token operator\">*</span>\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">RIGHT</span> <span class=\"token keyword\">OUTER</span> <span class=\"token keyword\">JOIN</span> students_department</code></pre></div>\n<h3 id=\"full-outer-join\" style=\"position:relative;\"><a href=\"#full-outer-join\" aria-label=\"full outer join permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Full Outer Join</h3>\n<p>Full Outer Join은 양쪽 테이블의 정보를 모두 유지한채로 테이블을 합치는 방법이다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 560px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 85%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACeElEQVQ4y3VU+1PaQBDmD+/P1RmtLT4wiHam/amdjrVTay0FC6EKIg9RZ5zWRyVJfRWCBCW8knzduyNNgvRmdrL33e23H7u3hDCyHMfB/9bombv34yH/oXtgWRb/2raNfr/v3vgXxHB3P5okQCguAuVyGV8TSeRyOWQyGchyBmtrqzj+8RP7pSI+b26icnA4XqFfmfDBVen1Osx2G0arhevrG6iqhvsH2jfv0GjoaNOZRQKCsY4gHM0y6HVR05u4+aOjT767rH6P8Dvc1hoB3M8RCpDZA+wcXkBKVhH+piOcaiCSVJEun2GncoZoUuH4bOoOkYSCVPkXJekGSMVP5oiF9dwpplIPkEpAtAgs0TeyBzx5c4yZVAuLQ5wb+dNyF2/lE9LR8xTatmA+OFExtdXEyj5d3rMh5W3EysDkJxXhtIGVyhDfc7gxn92dTreRPaoOu89qyIvTw7usgvk8qSoMA0jFQraHiXUFS+RzrMBIHWEFkSBCZ69klepues+m2zHxMq1hseipYCRz301MbmhcqUQ4I/ETu4nnExpM00fY75p4nRlDuD2eUPIpZPWWtjR0zLYgFCV08KVQxYsdC7FiMOjpxwss7g6oFB7uWozKM7sLvM9eEMWAN5cIRVNqdXoOcZXXZLkksi+TsnCqiYmNS0TJj5VEjZkxXyJsJn4F9fLWa4rrsHWuXGGB3tczuYM5ahCz59sDTK1WEImfYybTxRwpYs1j/mziN45ONUHmf4d+wDCa2D5U8CGvcZMrVTQNA/ctI4CnKwrquu7FDsc25M6vX6mYM5oAq/P4P8ymRzzwcJfs0ej559GyxfQw4/7wfBw+Gv8XozziAwPFjbMAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"fullouterjoin\"\n        title=\"fullouterjoin\"\n        src=\"/static/cb3bd1e595fc0a3dc85f4daf0e57e002/b06ae/fullouterjoin.png\"\n        srcset=\"/static/cb3bd1e595fc0a3dc85f4daf0e57e002/5a46d/fullouterjoin.png 300w,\n/static/cb3bd1e595fc0a3dc85f4daf0e57e002/b06ae/fullouterjoin.png 560w\"\n        sizes=\"(max-width: 560px) 100vw, 560px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>위에서 계속 사용했던 아래 테이블을 full outer join 으로 합쳐보자</p>\n<p>students_info</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">국인</td>\n<td align=\"center\">22</td>\n<td align=\"center\">M</td>\n</tr>\n</tbody>\n</table>\n<p>students_department</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">SWFL</td>\n</tr>\n</tbody>\n</table>\n<p>두 테이블을 합치면,</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\"><U>student_id</U></th>\n<th align=\"center\">student_name</th>\n<th align=\"center\">age</th>\n<th align=\"center\">sex</th>\n<th align=\"center\">Department</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">1</td>\n<td align=\"center\">여훈</td>\n<td align=\"center\">26</td>\n<td align=\"center\">M</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">2</td>\n<td align=\"center\">윤이</td>\n<td align=\"center\">24</td>\n<td align=\"center\">F</td>\n<td align=\"center\">CPSW</td>\n</tr>\n<tr>\n<td align=\"center\">3</td>\n<td align=\"center\">현기</td>\n<td align=\"center\">21</td>\n<td align=\"center\">M</td>\n<td align=\"center\">CSEE</td>\n</tr>\n<tr>\n<td align=\"center\">4</td>\n<td align=\"center\">국인</td>\n<td align=\"center\">22</td>\n<td align=\"center\">M</td>\n<td align=\"center\">null</td>\n</tr>\n<tr>\n<td align=\"center\">5</td>\n<td align=\"center\">null</td>\n<td align=\"center\">null</td>\n<td align=\"center\">null</td>\n<td align=\"center\">SWFL</td>\n</tr>\n</tbody>\n</table>\n<p>이렇게 두 양쪽 테이블의 정보를 모두 포함한 테이블이 만들어진다. 비어있는 값은 null 로 초기화된다.</p>\n<p>MySQL 에서는 Full Outer Join의 쿼리를 지원하지 않는다. 그래서 우리는 직접 이 쿼리를 만들어서 사용할 수 있는데, 양쪽 정보를 모두 포함시키려면, Left Outer Join 과 Right Outer Join 의 내용을 모두 포함하는 것임으로 UNION 연산을 통해 왼쪽 기준으로 조인한 테이블, 오른쪽 기준으로 조인한 테이블을 합쳐주면 된다.</p>\n<p>쿼리문은 다음과 같이 작성할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">SELECT</span> student_id<span class=\"token punctuation\">,</span> student_name<span class=\"token punctuation\">,</span> age<span class=\"token punctuation\">,</span> sex<span class=\"token punctuation\">,</span> Department\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">LEFT</span> <span class=\"token keyword\">OUTER</span> <span class=\"token keyword\">JOIN</span> students_Department\n\n<span class=\"token keyword\">UNION</span>\n\n<span class=\"token keyword\">SELECT</span> student_id<span class=\"token punctuation\">,</span> student_name<span class=\"token punctuation\">,</span> age<span class=\"token punctuation\">,</span> sex<span class=\"token punctuation\">,</span> Department\n<span class=\"token keyword\">FROM</span> students_info <span class=\"token keyword\">NATURAL</span> <span class=\"token keyword\">RIGHT</span> <span class=\"token keyword\">OUTER</span> <span class=\"token keyword\">JOIN</span> students_Department<span class=\"token punctuation\">;</span></code></pre></div>\n<p>이렇게 두 쿼리를 합쳐주는 것으로 Full Outer Join을 구현할 수 있다. 하지만 명심해야할 부분은 UNION 같은 집합 연산자를 사용할 때는 두 테이블의 attrbitue의 순서가 동일해야하기 때문에, SELECT 문에서 attribute의 순서를 지정해줘야한다.</p>","frontmatter":{"title":"[데이터베이스] 조인연산(Join Operations in SQL)","date":"April 13, 2020"}}},"pageContext":{"slug":"/Database/2020-04-13-데이터베이스-조인연산/","previous":{"fields":{"slug":"/Database/2020-04-11-데이터베이스-키/"},"frontmatter":{"title":"[데이터베이스] 키(Key)","category":"Database","draft":false}},"next":{"fields":{"slug":"/Algorithm-Analysis/2020-04-14-알고리즘-배낭문제/"},"frontmatter":{"title":"[알고리즘 정리] 배낭 문제(Knapsack Problem)","category":"Algorithm-Analysis","draft":false}}}},"staticQueryHashes":["2486386679","3128451518"]}