<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>working_helen</title>
    <link>https://working-helen.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 16 Apr 2026 11:20:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>HaeWon_Seo</managingEditor>
    <image>
      <title>working_helen</title>
      <url>https://tistory1.daumcdn.net/tistory/6450937/attach/6be94d54a05848e0b731e08a1823ce08</url>
      <link>https://working-helen.tistory.com</link>
    </image>
    <item>
      <title>[코테 연습] HackerRank 코딩테스트 연습 Medium &amp;amp; Hard</title>
      <link>https://working-helen.tistory.com/177</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HackerRank 코딩테스트 연습 Medium &amp;amp; Hard&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Occupations&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: pivot the Occupation column in OCCUPATIONS so that each Name is sorted alphabetically and displayed underneath its corresponding Occupation. The output should consist of four columns (Doctor, Professor, Singer, and Actor) in that specific order, with their respective names listed alphabetically under each column.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caf5L3/btsO0FffEhV/BW3PIfHbttNKkfWW6ZHMC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caf5L3/btsO0FffEhV/BW3PIfHbttNKkfWW6ZHMC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caf5L3/btsO0FffEhV/BW3PIfHbttNKkfWW6ZHMC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcaf5L3%2FbtsO0FffEhV%2FBW3PIfHbttNKkfWW6ZHMC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;155&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&amp;nbsp;&lt;b&gt;&amp;gt; PIVOT 함수&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751513264845&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT *
FROM 테이블명
PIVOT (VALUE칼럼 FOR UNSTACK칼럼 IN (값1, 값2, 값3, ...))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 기존 테이블에는 있지만 PIVOT 함수 내에서는 사용되지 않은 칼럼들&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; PIVOT 결과에서 STACK 칼럼 역할을 함, 해당 칼럼들 조합별로 UNSTACK 칼럼 집계&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- VALUE 칼럼에는 반드시 집계 함수 사용해야 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- PIVOT 이후에 정렬 : 기존 테이블에 있던 칼럼을 기준으로 정렬 가능&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- FROM절 서브쿼리에서 RNK를 정의&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; PIVOT 결과에서 RNK 칼럼을 STACK 칼럼으로 사용하여 집계하므로&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; VALUE 칼럼에서 집계함수 사용을 위해 MAX(NAME)를 해주어도 모든 NAME 출력 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; PIVOT 테이블을 RNK를 기준으로 정렬 가능&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- OCCUPATION에 해당되는 NAME이 없으면 MAX( NULL )은 NULL 리턴&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751513264851&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT Doctor, Professor, Singer, Actor
FROM (
    SELECT NAME, OCCUPATION,
        RANK() OVER (PARTITION BY OCCUPATION ORDER BY NAME) AS RNK
    FROM OCCUPATIONS)
PIVOT (
    MAX(NAME)
    FOR OCCUPATION IN ('Doctor' AS Doctor,
                       'Professor' AS Professor,
                       'Singer' AS Singer,
                       'Actor' AS Actor)
    )
ORDER BY RNK;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- row_number 값을 그루핑에 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 각 OCCUPATION마다 RN 값이 하나씩 배정되므로&amp;nbsp;각 RN 그룹 내에서 OCCUPTAION 4개로 나누기&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- OCCUPATION에 해당되는 NAME이 없으면 MAX( NULL )은 NULL 리턴&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751513264859&quot; class=&quot;pgsql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT
    MAX(CASE WHEN OCCUPATION = 'Doctor' THEN NAME END) AS Doctor,
    MAX(CASE WHEN OCCUPATION = 'Professor' THEN NAME END) AS Professor,
    MAX(CASE WHEN OCCUPATION = 'Singer' THEN NAME END) AS Singer,
    MAX(CASE WHEN OCCUPATION = 'Actor' THEN NAME END) AS Actor
FROM (
    SELECT NAME, OCCUPATION,
         ROW_NUMBER() OVER (PARTITION BY OCCUPATION ORDER BY NAME) AS RN
    FROM OCCUPATIONS) TMP
GROUP BY RN
ORDER BY RN;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Symmetric&amp;nbsp;Pairs&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Two&amp;nbsp;pairs&amp;nbsp;(X1,&amp;nbsp;Y1)&amp;nbsp;and&amp;nbsp;(X2,&amp;nbsp;Y2)&amp;nbsp;are&amp;nbsp;said&amp;nbsp;to&amp;nbsp;be&amp;nbsp;symmetric&amp;nbsp;pairs&amp;nbsp;if&amp;nbsp;X1&amp;nbsp;=&amp;nbsp;Y2&amp;nbsp;and&amp;nbsp;X2&amp;nbsp;=&amp;nbsp;Y1.&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;query&amp;nbsp;to&amp;nbsp;output&amp;nbsp;all&amp;nbsp;such&amp;nbsp;symmetric&amp;nbsp;pairs&amp;nbsp;in&amp;nbsp;ascending&amp;nbsp;order&amp;nbsp;by&amp;nbsp;the&amp;nbsp;value&amp;nbsp;of&amp;nbsp;X.&amp;nbsp;List&amp;nbsp;the&amp;nbsp;rows&amp;nbsp;such&amp;nbsp;that&amp;nbsp;X1&amp;nbsp;&amp;le;&amp;nbsp;Y1. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nbrak/btsO2zTZpN8/kWvNEEgHtLKljdIl6Lzuw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nbrak/btsO2zTZpN8/kWvNEEgHtLKljdIl6Lzuw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nbrak/btsO2zTZpN8/kWvNEEgHtLKljdIl6Lzuw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnbrak%2FbtsO2zTZpN8%2FkWvNEEgHtLKljdIl6Lzuw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;296&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;664&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bemuUW/btsO1AMlWfu/TS1DeohHqBSKDceOpRCRBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bemuUW/btsO1AMlWfu/TS1DeohHqBSKDceOpRCRBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bemuUW/btsO1AMlWfu/TS1DeohHqBSKDceOpRCRBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbemuUW%2FbtsO1AMlWfu%2FTS1DeohHqBSKDceOpRCRBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;153&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(X1, Y1) = (20, 20), (X2, Y2) = (20,20), (X3, Y3) = (10,10) 인 경우&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;그냥 cartessian product 수행한 후 X1=Y2, X2=Y1 조건으로 필터링하면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;(X1, Y1)과 (X2, Y2)을 원하는 &lt;span style=&quot;text-align: start;&quot;&gt;symmetric pairs로 찾아낼 수 있지만&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;자기 자신과 pair가 되는 (X3, Y3)과 (X3, Y3) 경우도 &lt;span style=&quot;text-align: start;&quot;&gt;symmetric pairs로 인식되어 버리는 문제 발생&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;풀이 1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;- 각 (X, Y)가 고유하게 인식될 수 있도록 index 만들어버리기&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;- row_number 사용해서 행에 index 붙히기&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751520691848&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with tmp as (
    select x, y, row_number() over(order by x, y) as rn
    from functions
) 
select distinct t1.x, t1.y 
from tmp t1 join tmp t2
    on t1.x = t2.y  and t1.y = t2.x and t1.rn != t2.rn
where t1.x &amp;lt;= t1.y
order by 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;풀이 2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 두 (X, Y)가 완전히 동일해서 &lt;span style=&quot;text-align: start;&quot;&gt;symmetric pairs인 경우와&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp; 두 (X, Y)가 동일하지 않으면서 &lt;span style=&quot;text-align: start;&quot;&gt;symmetric pairs 경우, 2가지를 분리해서 구한 후 UNION&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;- (X, Y)로 그루핑 &amp;rarr; COUNT(*) &amp;gt; 1이면 2개 이상의 &lt;span style=&quot;text-align: start;&quot;&gt;(X, Y)가 완전히 동일하면서&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;symmetric pairs인 경우&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751520774995&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select x, y
from (select x, y 
    from functions 
    where  x = y
    group by x, y 
    having count(*) &amp;gt; 1
    union all
    select distinct f1.x, f1.y
    from functions f1 
    join functions f2 on f1.x = f2.y and f1.y = f2.x
                      and f1.x != f2.x and f1.y != f2.y
) tmp
where x &amp;lt;= y
order by 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;SQL&amp;nbsp;Project&amp;nbsp;Planning&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: If the End_Date of the tasks are consecutive, then they are part of the same project. Samantha is interested in finding the total number of different projects completed. Write a query to output the start and end dates of projects listed by the number of days it took to complete the project in ascending order. If there is more than one project that have the same number of completion days, then order by the start date of the project.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FKEEX/btsO4mF1pZx/Y2yJpIjD43jPt0JoLAgHT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FKEEX/btsO4mF1pZx/Y2yJpIjD43jPt0JoLAgHT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FKEEX/btsO4mF1pZx/Y2yJpIjD43jPt0JoLAgHT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFKEEX%2FbtsO4mF1pZx%2FY2yJpIjD43jPt0JoLAgHT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;295&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;656&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8MqWb/btsO3NjKKJF/u7QiaAitK1VIsky3AT6u2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8MqWb/btsO3NjKKJF/u7QiaAitK1VIsky3AT6u2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8MqWb/btsO3NjKKJF/u7QiaAitK1VIsky3AT6u2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8MqWb%2FbtsO3NjKKJF%2Fu7QiaAitK1VIsky3AT6u2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;542&quot; height=&quot;158&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 같은 프로젝트이면 end_date가 하나씩 차이 + end_date 기준으로 정렬했을때 row_number도 하나씩 차이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 같은 프로젝트이다 &amp;rarr; &lt;span style=&quot;text-align: start;&quot;&gt;end_date -&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;row_number 값이 같다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;rarr; &lt;span style=&quot;text-align: start;&quot;&gt;end_date&amp;nbsp;-&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;row_number 값으로 프로젝트 그루핑하기!&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751589880688&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with tmp as (
    select start_date, end_date,
        end_date - row_number() over(order by end_date) as gp
    from Projects
)
select min(start_date), max(end_date)
from tmp
group by gp
order by max(end_date)-min(start_date), min(start_date);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;15&amp;nbsp;Days&amp;nbsp;of&amp;nbsp;Learning&amp;nbsp;SQL&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Conducted a&amp;nbsp;&amp;nbsp;days of learning SQL contest. The start date of the contest was March 01, 2016 and the end date was March 15, 2016. Write a query to print total number of unique hackers who made at least&amp;nbsp;&amp;nbsp;submission each day (starting on the first day of the contest), and find the hacker_id and name of the hacker who made maximum number of submissions each day. If more than one such hacker has a maximum number of submissions, print the lowest hacker_id. The query should print this information for each day of the contest, sorted by the date.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cx9bt/btsPgxAQrMV/7CwX3A19ZKf7GORN5ETg70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cx9bt/btsPgxAQrMV/7CwX3A19ZKf7GORN5ETg70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cx9bt/btsPgxAQrMV/7CwX3A19ZKf7GORN5ETg70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCx9bt%2FbtsPgxAQrMV%2F7CwX3A19ZKf7GORN5ETg70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;441&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번 문제는 다 해결하지 못해 Leaderboard 내 솔루션을 참고했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Hacker&amp;nbsp;아이디&amp;nbsp;:&amp;nbsp;L0r3nz0&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;솔루션 출처 : &lt;a style=&quot;color: #000000;&quot; href=&quot;https://www.hackerrank.com/rest/contests/master/challenges/15-days-of-learning-sql/hackers/L0r3nz0/download_solution?primary=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/rest/contests/master/challenges/15-days-of-learning-sql/hackers/L0r3nz0/download_solution?primary=true&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SUB_DAY : submission_date, hacker_id, name 별로 제출될 submissions 개수 세기 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;RNK : submission_date별로 subs 값이 최대인 해커들 중에서 hacker_id가 가장 작은 한 명만 선택&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CONSEC : &lt;b&gt;계층형 쿼리로 연속된 날짜 동안 모두 존재하는 record 찾기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;START WITH : '2016-03-01'에 제출한 해커를 기준으로 시작&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CONNECT BY&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;u&gt;같은 hacker_id의 해커가 그 다음날 제출한 record가 있으면 계층형 쿼리 연결&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;같은 hacker_id의 해커가 그 다음날 제출한 record가 없으면 해당 날짜 이후부터 계층형 탐색에 포함되지 않음&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;background-color: #fcfcfc; color: #000000; text-align: left;&quot;&gt;➡️&lt;/span&gt;&lt;b&gt; '2016-03-01'부터 각 해커가 연속으로 제출한 날짜까지만 CONSEC에 포함!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최종 출력 SELECT문&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SUB_DAY 테이블에 submission_date를 기준으로 CONSEC 정보를 LEFT JOIN&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr; count(CONSEC에서의 hacker_id 개수)로 연속으로 제출한 해커 수 세기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SUB_DAY 테이블에 submission_date를 기준으로 RNK 정보를 LEFT JOIN&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;같은&lt;span style=&quot;text-align: left;&quot;&gt;&amp;nbsp;submission_date에는 모두 같은&amp;nbsp;r.hacker_id,&amp;nbsp;r.name&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&amp;rarr; group by 집계함수를 사용해야 하므로 그냥 MIN, MAX 사용해버기 스킬&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1752393372222&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH SUBS_DAY AS (
    SELECT submission_date, hacker_id, name, COUNT(*) AS subs
    FROM SUBMISSIONS s LEFT JOIN HACKERS h USING(hacker_id)
    GROUP BY submission_date, hacker_id, name
),
RNK AS (
    SELECT submission_date, hacker_id, name
    FROM (SELECT submission_date, hacker_id, name,
               ROW_NUMBER() OVER (PARTITION BY submission_date
                                ORDER BY subs DESC, hacker_id ASC) AS rn
          FROM SUBS_DAY) tmp
    WHERE rn = 1
),
CONSEC AS (
SELECT hacker_id, name, submission_date, subs
    FROM SUBS_DAY
    START WITH submission_date = DATE '2016-03-01'
    CONNECT BY 
        PRIOR submission_date = submission_date - 1
        AND PRIOR hacker_id = hacker_id
)
SELECT
    sd.submission_date, COUNT(c.hacker_id) AS dist_hacker_subs,
    MIN(r.hacker_id), MIN(r.name)
FROM SUBS_DAY sd LEFT JOIN CONSEC c 
        ON c.submission_date = sd.submission_date AND c.hacker_id = sd.hacker_id
    LEFT JOIN RNK r ON r.submission_date = sd.submission_date
GROUP BY sd.submission_date
ORDER BY 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/177</guid>
      <comments>https://working-helen.tistory.com/177#entry177comment</comments>
      <pubDate>Sun, 13 Jul 2025 17:04:17 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] HackerRank 코딩테스트 연습 Easy &amp;amp; Medium</title>
      <link>https://working-helen.tistory.com/175</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HackerRank 코딩테스트 연습 Easy &amp;amp; Medium&amp;nbsp;&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Weather Observation Station 5&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Query the two cities in STATION with the shortest and longest CITY names, as well as their respective lengths (i.e.: number of characters in the name). If there is more than one smallest or largest city, choose the one that comes first when ordered alphabetically.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBDBLy/btsOYxV91v0/H0ApSgC7W4ivRHFDJspsH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBDBLy/btsOYxV91v0/H0ApSgC7W4ivRHFDJspsH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBDBLy/btsOYxV91v0/H0ApSgC7W4ivRHFDJspsH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBDBLy%2FbtsOYxV91v0%2FH0ApSgC7W4ivRHFDJspsH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;248&quot; height=&quot;225&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;545&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 정렬만을 가지고 쉽게 record를 얻기 위해&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; LENGTH(CITY) 오름차순 정렬했을 때, 내림차순 정렬했을 때, 따로따로 진행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;- ROW_NUMBER(), RANK() 다 가능 / DENSE_RANK()는 불가능&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751343867455&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH TBL AS (
  SELECT CITY, LENGTH(CITY) AS LEN,
         ROW_NUMBER() OVER (ORDER BY LENGTH(CITY), CITY) AS RN_MIN,
         ROW_NUMBER() OVER (ORDER BY LENGTH(CITY) DESC, CITY) AS RN_MAX
  FROM STATION
)
SELECT CITY, LEN
FROM TBL
WHERE RN_MIN = 1 OR RN_MAX = 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 원하는 정보 하나씩 추출한 후 UNION하기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- where절에서 rownum을 사용하기 위해 서브쿼리로 묶기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 절대적인 행 번호가 아닌 가상의 번호이므로 '&amp;lt;' 연산만 가능&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751344051684&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(
    SELECT CITY, LENGTH(CITY) AS LEN
    FROM (
      SELECT CITY
      FROM STATION
      ORDER BY LENGTH(CITY), CITY
    )
    WHERE ROWNUM = 1
) UNION (
    SELECT CITY, LENGTH(CITY) AS LEN
    FROM (
      SELECT CITY
      FROM STATION
      ORDER BY LENGTH(CITY) DESC, CITY
    )
    WHERE ROWNUM = 1
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Draw&amp;nbsp;The&amp;nbsp;Triangle&amp;nbsp;1&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #35363f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #35363f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: P(R) represents a pattern drawn by Julia in R rows. The following pattern represents P(5). Write a query to print the pattern P(20).&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;markdown&quot; style=&quot;background-color: #f7f8fd; color: #121418; text-align: start;&quot;&gt;&lt;code&gt;* * * * * 
* * * * 
* * * 
* * 
*
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 테이블 없이 SQL로 결과를 리턴하고 싶을 때, &lt;b&gt;FROM DUAL&lt;/b&gt; 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;RPAD(대상 문자열, n, 추가 문자열)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;'대상 문자열'의 오른쪽에, '추가 문자열'을 연결해서, 길이가 n까지 리턴&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때 '추가 문자열' 연결로 길이가 n 이상이 되면, 연결 후 n까지만 잘려서 리턴&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; START WITH 없이 CONNECT BY&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; 특정한 행을 root로 지정하지 않고 가능한 가능한 모든 경로를 탐색하는 계층형 쿼리&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Oracle이 알아서&lt;u&gt; DUAL 테이블에서 LEVEL = 1부터 시작해서 계층형 탐색&lt;/u&gt; 진행&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LEVEL 20까지만 탐색하기 위해, 탐색에서 &lt;u&gt;연결 조건을 지정하는 CONNECT BY를 사용&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1751347952760&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT RPAD('* ', 2*LEVEL-1, '* ') AS PATTERN
FROM DUAL
CONNECT BY LEVEL &amp;lt;= 20
ORDER BY LEVEL DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;The&amp;nbsp;PADS&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession as a parenthetical (i.e.: enclosed in parentheses). For example: AnActorName(A), ADoctorName(D), ProfessorName(P), and ASingerName(S). Query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format: &quot;There are a total of [occupation_count] [occupation]s.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6MK3b/btsOYRtY9Sr/e1U30oRFoXeSbTY9MCXEQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6MK3b/btsOYRtY9Sr/e1U30oRFoXeSbTY9MCXEQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6MK3b/btsOYRtY9Sr/e1U30oRFoXeSbTY9MCXEQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6MK3b%2FbtsOYRtY9Sr%2Fe1U30oRFoXeSbTY9MCXEQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;298&quot; height=&quot;242&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;516&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FIQde/btsOZVWa1Iu/chjtRAo4ndAuVxOWW5XkR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FIQde/btsOZVWa1Iu/chjtRAo4ndAuVxOWW5XkR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FIQde/btsOZVWa1Iu/chjtRAo4ndAuVxOWW5XkR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFIQde%2FbtsOZVWa1Iu%2FchjtRAo4ndAuVxOWW5XkR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;355&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; Oracle에서 문자열 연결&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CONCAT(문자열1, 문자열2) : 2개의 문자열을 연결할 때 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문자열1 || 문자열2 || 문자열3 || ... : 3개 이상의 문자열을 연결할 때 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- UNION 사용시 &lt;u&gt;개별 쿼리 내에서 ORDER BY를 사용할 수 없음!&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; &lt;u&gt;정렬에 사용할 칼럼을 서브쿼리 내에서 별도로 리턴하기&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 여러 개의 쿼리 결과를 한번에 리턴하는 경우&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;rarr; 쿼리 순서대로 출력될 수 있도록 &lt;u&gt;쿼리의 순서를 의미하는 칼럼을 서브쿼리 내에서 리턴&lt;/u&gt;하기&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751350559974&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT OUTPUT
FROM(
    SELECT NAME || '(' || (CASE WHEN OCCUPATION = 'Actor' THEN 'A'
                            WHEN OCCUPATION = 'Doctor' THEN 'D'
                            WHEN OCCUPATION = 'Professor' THEN 'P'
                            ELSE 'S' END) || ')' AS OUTPUT,
            NAME AS FIRST_ORDER, NULL AS SEC_ORDER, '1' AS QUEST_ORDER
    FROM OCCUPATIONS
    UNION
    SELECT 'There are a total of ' || COUNT(*) || ' ' || LOWER(OCCUPATION) || 's.' AS OUTPUT,
            TO_CHAR(COUNT(*)) AS FIRST_ORDER, OCCUPATION AS SEC_ORDER, '2' AS QUEST_ORDER
    FROM OCCUPATIONS
    GROUP BY OCCUPATION
    ) TMP
ORDER BY QUEST_ORDER, FIRST_ORDER, SEC_ORDER;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;The&amp;nbsp;Report&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: You are given two tables: Students and Grades. Generate a report containing three columns: Name, Grade and Mark. Ketty doesn't want the NAMES of those students who received a grade lower than 8. The report must be in descending order by grade. If there is more than one student with the same grade (8-10) assigned to them, order those particular students by their name alphabetically. Finally, if the grade is lower than 8, use &quot;NULL&quot; as their name and list them by their grades in descending order.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zacns/btsO0Eg42ZQ/OtfRmKWps1L1PJtxZEZ1E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zacns/btsO0Eg42ZQ/OtfRmKWps1L1PJtxZEZ1E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zacns/btsO0Eg42ZQ/OtfRmKWps1L1PJtxZEZ1E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzacns%2FbtsO0Eg42ZQ%2FOtfRmKWps1L1PJtxZEZ1E0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;519&quot; height=&quot;187&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 원하는 정보 하나씩 추출한 후 UNION하기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- UNION 사용시&amp;nbsp;&lt;u&gt;개별 쿼리 내에서 ORDER BY를 사용할 수 없음!&lt;/u&gt;&lt;u&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp; &amp;rarr;&amp;nbsp;&lt;/span&gt;정렬에 사용할 칼럼을 서브쿼리 내에서 별도로 리턴하기 (여기서는 GRADE, NAME으로 정렬)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ON절 조건을 사용해 &lt;span style=&quot;text-align: start;&quot;&gt;JOIN 방법에 관한 조건을 설정&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp; JOIN을 할 때 G의 MIN_MARK와 MAX_MARK 값을 S의 MAKRS 값과 비교하도록&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751511280682&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH TMP AS (
    SELECT NAME, GRADE, MARKS
    FROM STUDENTS S JOIN GRADES G
        ON S.MARKS BETWEEN G.MIN_MARK AND G.MAX_MARK
)
SELECT * FROM TMP
WHERE GRADE &amp;gt; 7
UNION
SELECT NULL AS NAME, GRADE, MARKS FROM TMP
WHERE GRADE &amp;lt;= 7
ORDER BY 2 DESC, 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Binary&amp;nbsp;Tree&amp;nbsp;Nodes &lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;You&amp;nbsp;are&amp;nbsp;given&amp;nbsp;a&amp;nbsp;table,&amp;nbsp;BST,&amp;nbsp;containing&amp;nbsp;two&amp;nbsp;columns:&amp;nbsp;N&amp;nbsp;and&amp;nbsp;P,&amp;nbsp;where&amp;nbsp;N&amp;nbsp;represents&amp;nbsp;the&amp;nbsp;value&amp;nbsp;of&amp;nbsp;a&amp;nbsp;node&amp;nbsp;in&amp;nbsp;Binary&amp;nbsp;Tree,&amp;nbsp;and&amp;nbsp;P&amp;nbsp;is&amp;nbsp;the&amp;nbsp;parent&amp;nbsp;of&amp;nbsp;N.&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;query&amp;nbsp;to&amp;nbsp;find&amp;nbsp;the&amp;nbsp;node&amp;nbsp;type&amp;nbsp;of&amp;nbsp;Binary&amp;nbsp;Tree&amp;nbsp;ordered&amp;nbsp;by&amp;nbsp;the&amp;nbsp;value&amp;nbsp;of&amp;nbsp;the&amp;nbsp;node.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/etrohm/btsO3GLb1ec/dnS8elQpoKulYehvn2PWkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/etrohm/btsO3GLb1ec/dnS8elQpoKulYehvn2PWkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/etrohm/btsO3GLb1ec/dnS8elQpoKulYehvn2PWkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fetrohm%2FbtsO3GLb1ec%2FdnS8elQpoKulYehvn2PWkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;223&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;gt; col값 IN (비교값1, 비교값 2, 비교값3, ...)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IN 은 col값을 리스트 내에 있는 모든 비교값과 '=' 연산 + 'or' 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; '='를 만족하는 비교값이 적어도 하나 있으면 True를 리턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비교값에 NULL이 있더라도 True를 리턴하는 비교값이 하나라도 있으면 True를 리턴하므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 즉 &lt;u&gt;IN 함수는&amp;nbsp;비교값 리스트에 NULL이 있든 없든 영향을 받지 않음&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;gt; col값 NOT IN &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(비교값1,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;비교값 2,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;비교값3, ...) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NOT IN은 col값을 리스트 내에 있는 모든 비교값과 '=' 연산 + 'and' 연결&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'='를 만족하지 않는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;비교값이 하나라도 있으면 True를 리턴&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 비교값에 NULL이 있으면 col값이 무엇이든 NULL과의 '=' 연산은 unknown으로 False 취급되므로&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;u&gt;실제로 col값이 리스트 내에 없어 True가 나와야하지만 NULL과의 비교로 인해 Fasle가 출력될 수 있음&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 정확한 비교를 비교해서 &lt;u&gt;NOT IN 함수는&amp;nbsp;비교값 리스트에 NULL이 없어야 함&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; NOT NULL로 제거, NOT EXISTS로 대체 등 방법 이용&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이 1 : IN 사용&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1751521714920&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select N, case when P is null then 'Root'
            when N in (select distinct P from BST) then 'Inner'
            else 'Leaf' end
from BST
order by 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이 2 : NOT IN 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 비교값 리스트에서 not null 조건 넣어서 NULL 제거해야 함&lt;/p&gt;
&lt;pre id=&quot;code_1751521721392&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select N, case when P is null then 'Root'
            when N not in (select distinct P from BST where P is not null) then 'Leaf'
            else 'Inner' end
from BST
order by 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/175</guid>
      <comments>https://working-helen.tistory.com/175#entry175comment</comments>
      <pubDate>Tue, 1 Jul 2025 13:41:26 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 Hard</title>
      <link>https://working-helen.tistory.com/173</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL&amp;nbsp; Hard&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;✅&lt;/span&gt;&lt;/span&gt;&amp;nbsp;계층형 질의&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 계층형 데이터 &lt;br /&gt;- 동일한 table 내 행끼리 상위/하위 관계가 있는 경우 &lt;br /&gt;- 하나의 table에서 특정 행이 다른 행의 상위(부모) 또는 하위(자식) 역할을 하는 데이터 구조&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층형 데이터는 트리 구조로 설명 가능&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;root&amp;nbsp;node&amp;nbsp;:&amp;nbsp;최상위&amp;nbsp;부모&amp;nbsp;행&lt;/li&gt;
&lt;li&gt;leaf node : 자식이 없는 최하위 행&lt;/li&gt;
&lt;li&gt;depth : root node 로부터 특정 노드까지의 거리, root부터 1이며 leaf로 내려갈 때마다 1씩 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 계층형 질의 Hierarchical Query&amp;nbsp;&lt;br /&gt;- 계층형 데이터를 탐색하기 위한 SQL문 &lt;br /&gt;- 계층형 데이터를 특정 시작 지점부터 상위/하위 관계를 따라 depth를 탐색하며 쿼리 수행&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1750989708863&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 칼럼명
FROM 테이블명
START WITH 시작지점
CONNECT BY [ NOCYCLE ] PRIOR 연결조건&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;START WITH : 쿼리 처리가 시작되는 행을 지정&lt;/li&gt;
&lt;li&gt;CONNECT BY : 행과 행을 연결해나가는 조건 지정&lt;/li&gt;
&lt;li&gt;PRIOR : 상위(부모)-하위(자식) 관계의 방향 지정에 사용&amp;nbsp;&lt;/li&gt;
&lt;li&gt;NOCYCLE : 연결 과정에서 순환 구조가 생기는 것을 방지하여 무한 루프 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층형&amp;nbsp;질의&amp;nbsp;가상&amp;nbsp;컬럼&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;LEVEL : 각 행의 depth를 리턴&lt;/li&gt;
&lt;li&gt;CONNECT_BY_ISLEAF : leaf node이면 1, 아니면 0을 리턴&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;계층형&amp;nbsp;질의&amp;nbsp;가상&amp;nbsp;함수&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;CONNECT_BY_ROOT 컬럼명 : 현재 행의 출발 root를 찾아 root의 칼럼 리턴&lt;/li&gt;
&lt;li&gt;SYS_CONNECT_BY_PATH(컬럼, 구분자) : root부터 현재 행까지 경로를 구분자로 연결해 출력&amp;nbsp;&lt;/li&gt;
&lt;li&gt;ORDER SIBLINGS BY 컬럼 : 같은 LEVEL의 행끼리 정렬 수행&amp;nbsp;&lt;/li&gt;
&lt;li&gt;CONNECT_BY_ISCYCLE : 계층형 쿼리에서 순환 구조 발생 여부 리턴&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 계층형 쿼리 예문 (위의 3482번 문제 table 활용)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGCK0g/btsOTYsjiQs/oy5i5SHoJsRLWjkRcNe8g1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGCK0g/btsOTYsjiQs/oy5i5SHoJsRLWjkRcNe8g1/img.png&quot; data-alt=&quot;Employees table&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGCK0g/btsOTYsjiQs/oy5i5SHoJsRLWjkRcNe8g1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGCK0g%2FbtsOTYsjiQs%2Foy5i5SHoJsRLWjkRcNe8g1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;307&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Employees table&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① &lt;span style=&quot;background-color: #dddddd;&quot;&gt;CONNECT BY PRIOR 자식칼럼 = 부모칼럼&lt;/span&gt;&lt;br /&gt;- 현재 행의 자식 칼럼이, 어떤 행의 부모 칼럼이 되도록, 다음 행을 찾아 연결 &lt;br /&gt;- 즉 상위 노드 &amp;rarr; 하위 노드 방향으로 &lt;u&gt;순방향 전개&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- `manager_id`가 NULL인 최상위 노드&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(LEVEL 1)&lt;/span&gt;부터 최하위 노드까지 아래로 탐색&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1750991143638&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, manager_id, employee_name
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237.png&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcCmZP/btsOUSR8yHf/yDielxTdwuqxDrD3slZiC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcCmZP/btsOUSR8yHf/yDielxTdwuqxDrD3slZiC1/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcCmZP/btsOUSR8yHf/yDielxTdwuqxDrD3slZiC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcCmZP%2FbtsOUSR8yHf%2FyDielxTdwuqxDrD3slZiC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;263&quot; data-filename=&quot;화면 캡처 2025-06-26 102237.png&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;②&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;CONNECT BY PRIOR 부모칼럼 = 자식칼럼&lt;/span&gt;&lt;br /&gt;- 현재 행의 부모 칼럼이, 어떤 행의 자식 칼럼이 되도록, 다음 행을 찾아 연결&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 즉 하위 노드 &amp;rarr; 상위 노드 방향으로&lt;span&gt;&amp;nbsp;&lt;u&gt;역&lt;/u&gt;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;방향 전개&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 자신이 `manager_id`인 하위 노드가 없는 최하위 노드 'Judy'부터 최상위 노드&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(LEVEL 1)&lt;/span&gt;까지 위로 탐색&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1750991449648&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, employee_name, manager_id
FROM employees
START WITH employee_name = 'Ivy'
CONNECT BY employee_id = PRIOR manager_id;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (1).png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwhJ5H/btsOUSkjueY/AS6ugKuiRXdjKMV2gBrcJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwhJ5H/btsOUSkjueY/AS6ugKuiRXdjKMV2gBrcJK/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwhJ5H/btsOUSkjueY/AS6ugKuiRXdjKMV2gBrcJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwhJ5H%2FbtsOUSkjueY%2FAS6ugKuiRXdjKMV2gBrcJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;143&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (1).png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 다양한 START WITH 조건&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- START WITH 조건을 통해 root node를 다양하게 지정 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;`manager_id`가 2 또는 3인 노드부터 최상위 노드로 보고 탐색&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1750991800634&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, manager_id, employee_name
FROM employees
START WITH manager_id IN (2, 3)
CONNECT BY PRIOR employee_id = manager_id;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (2).png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmPC1W/btsOTfuSprg/gHwR1qjyZ7PPkFTcUrWYvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmPC1W/btsOTfuSprg/gHwR1qjyZ7PPkFTcUrWYvK/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmPC1W/btsOTfuSprg/gHwR1qjyZ7PPkFTcUrWYvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmPC1W%2FbtsOTfuSprg%2FgHwR1qjyZ7PPkFTcUrWYvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;205&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (2).png&quot; data-origin-width=&quot;567&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ 다양한 계층형&amp;nbsp;질의&amp;nbsp;가상&amp;nbsp;함수 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CONNECT_BY_ROOT로&amp;nbsp;현재&amp;nbsp;행의&amp;nbsp;출발&amp;nbsp;root&amp;nbsp;찾기 &lt;br /&gt;- SYS_CONNECT_BY_PATH로 root부터 현재 행까지 경로 확인&lt;/p&gt;
&lt;pre id=&quot;code_1750991978499&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, manager_id, employee_name,
    CONNECT_BY_ROOT employee_name AS root_name,
    SYS_CONNECT_BY_PATH(employee_name, ' -&amp;gt; ') AS path
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (3).png&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y14gO/btsOUGK9TBS/kdDoIUkbtFJb5xhXXFskK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y14gO/btsOUGK9TBS/kdDoIUkbtFJb5xhXXFskK0/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y14gO/btsOUGK9TBS/kdDoIUkbtFJb5xhXXFskK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY14gO%2FbtsOUGK9TBS%2FkdDoIUkbtFJb5xhXXFskK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1132&quot; height=&quot;273&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (3).png&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1750992180564&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, manager_id, employee_name,
    CONNECT_BY_ROOT employee_name AS root_name,
    SYS_CONNECT_BY_PATH(employee_name, ' -&amp;gt; ') AS path
FROM employees
START WITH manager_id = 2
CONNECT BY PRIOR employee_id = manager_id;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (4).png&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QssBM/btsOTwPYQsa/MumDyyfI73T320bCLiVM3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QssBM/btsOTwPYQsa/MumDyyfI73T320bCLiVM3k/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QssBM/btsOTwPYQsa/MumDyyfI73T320bCLiVM3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQssBM%2FbtsOTwPYQsa%2FMumDyyfI73T320bCLiVM3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;743&quot; height=&quot;121&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (4).png&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ORDER&amp;nbsp;SIBLINGS&amp;nbsp;BY로&amp;nbsp;같은&amp;nbsp;LEVEL끼리는&amp;nbsp;employee_name&amp;nbsp;기준&amp;nbsp;정렬&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1750992477529&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_name, employee_id, manager_id
FROM employees
START WITH manager_id IS NULL
CONNECT BY NOCYCLE PRIOR employee_id = manager_id
ORDER SIBLINGS BY employee_name desc&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (5).png&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btxn3U/btsOTJWtguS/IWT7RP1RNe2zxvwrFAqSBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btxn3U/btsOTJWtguS/IWT7RP1RNe2zxvwrFAqSBK/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btxn3U/btsOTJWtguS/IWT7RP1RNe2zxvwrFAqSBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbtxn3U%2FbtsOTJWtguS%2FIWT7RP1RNe2zxvwrFAqSBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;501&quot; height=&quot;282&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (5).png&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ ORDER BY와 OVER SIBILINGS BY는 하나의 쿼리에서 같이 사용할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ORDER BY를 추가적으로 사용하고 싶다면 계층형 쿼리 결과를 FROM 서브쿼리로 받아서 사용&lt;/p&gt;
&lt;pre id=&quot;code_1750992639102&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM (
  SELECT LEVEL AS depth, employee_name, employee_id, manager_id
  FROM employees
  START WITH manager_id IS NULL
  CONNECT BY PRIOR employee_id = manager_id
  ORDER SIBLINGS BY employee_name
)
ORDER BY depth&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (6).png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcsizn/btsOUYdD2pN/HskzhGFyrqPs4tOeFelwm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcsizn/btsOUYdD2pN/HskzhGFyrqPs4tOeFelwm0/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcsizn/btsOUYdD2pN/HskzhGFyrqPs4tOeFelwm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcsizn%2FbtsOUYdD2pN%2FHskzhGFyrqPs4tOeFelwm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;277&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (6).png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⑤ CONNECT BY절과 WHERE절 비교&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 105px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;CONNECT&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;BY 절의 &lt;span&gt;조건&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;WHERE 절의 조건&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;계층을&amp;nbsp;어떻게&amp;nbsp;연결하여&amp;nbsp;구성할&amp;nbsp;것인지&amp;nbsp;정의&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;계층형&amp;nbsp;쿼리&amp;nbsp;실행이&amp;nbsp;완료된&amp;nbsp;결과&amp;nbsp;table에&amp;nbsp;대한&amp;nbsp;필터링&amp;nbsp;조건&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;탐색&amp;nbsp;과정&amp;nbsp;중에&amp;nbsp;적용되는&amp;nbsp;조건&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;탐색&amp;nbsp;완료&amp;nbsp;후에&amp;nbsp;적용되는&amp;nbsp;조건&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;해당&amp;nbsp;조건을&amp;nbsp;만족하지&amp;nbsp;않으면&amp;nbsp;하위&amp;nbsp;노드를&amp;nbsp;연결하지&amp;nbsp;않음&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;이&amp;nbsp;조건이&amp;nbsp;만족하지&amp;nbsp;않으면&amp;nbsp;쿼리&amp;nbsp;출력&amp;nbsp;결과에서&amp;nbsp;제외&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;&lt;b&gt;START WITH 절 행이 항상 출력됨&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;&lt;b&gt;START WITH 절 행도 제외 대상에 포함&lt;/b&gt;&lt;br /&gt;&lt;b&gt;출력되지 않을 수 있음&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- START WITH 절에서 지정한 'Alice'는 `department`가 'Sales'가 아니지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; CONNECT BY 조건에는 영향을 받지 않으므로 출력에는 포함됨&lt;/p&gt;
&lt;pre id=&quot;code_1750993366210&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, manager_id, employee_name, department
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id AND department = 'Sales'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (8).png&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B5oyy/btsOTObMQJg/bhEiAoZEUnIVIMoU6F73L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B5oyy/btsOTObMQJg/bhEiAoZEUnIVIMoU6F73L1/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B5oyy/btsOTObMQJg/bhEiAoZEUnIVIMoU6F73L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB5oyy%2FbtsOTObMQJg%2FbhEiAoZEUnIVIMoU6F73L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;176&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (8).png&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- START WITH 절에서 지정한 'Alice'는 `department`가 'Sales'가 아니여서 출력에서 제외&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;계층형 데이터 탐색 과정은 위와 동일하게 진행되므로 'Alice'가 여전히 LEVEL 1 노드&lt;/p&gt;
&lt;pre id=&quot;code_1750993568068&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LEVEL, employee_id, manager_id, employee_name, department
FROM employees
WHERE department = 'Sales'
START WITH manager_id IS NULL
CONNECT BY PRIOR employee_id = manager_id&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (7).png&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XXCRZ/btsOUylZA7O/AeAMnKMmy24M6JJujBCsfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XXCRZ/btsOUylZA7O/AeAMnKMmy24M6JJujBCsfK/img.png&quot; data-alt=&quot;쿼리 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XXCRZ/btsOUylZA7O/AeAMnKMmy24M6JJujBCsfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXXCRZ%2FbtsOUylZA7O%2FAeAMnKMmy24M6JJujBCsfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;644&quot; height=&quot;156&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (7).png&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쿼리 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3482.&amp;nbsp;Analyze&amp;nbsp;Organization&amp;nbsp;Hierarchy&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Hierarchy Levels: For each employee, determine their level in the organization (CEO is level 1, employees reporting directly to the CEO are level 2, and so on).&lt;/li&gt;
&lt;li&gt;Team Size: For each employee who is a manager, count the total number of employees under them (direct and indirect reports).&lt;/li&gt;
&lt;li&gt;Salary Budget: For each manager, calculate the total salary budget they control (sum of salaries of all employees under them, including indirect reports, plus their own salary).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;697&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byQGDA/btsOsxv08c8/gK60XuCwz2KmcJwGbGONlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byQGDA/btsOsxv08c8/gK60XuCwz2KmcJwGbGONlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byQGDA/btsOsxv08c8/gK60XuCwz2KmcJwGbGONlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyQGDA%2FbtsOsxv08c8%2FgK60XuCwz2KmcJwGbGONlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;649&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;697&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① 모든 직원마다 한 번씩 root로 삼아 자신의 하위 조직 전체를 탐색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CONNECT BY만 쓰고 START WITH를 생략하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;모든 행을 root 후보로 생각하고&lt;/b&gt;&amp;nbsp;가능한 &lt;b&gt;모든&lt;span&gt;&amp;nbsp;&lt;/span&gt;계층 경로를 탐색 &lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;rarr; &quot;&lt;/span&gt;&lt;b&gt;Cartesian-style traversal&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층형 쿼리를 작성하되 START WITH 절을 생략하기 + CONNECT_BY_ROOT로 root 노드 정보 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;rarr; &lt;b&gt;가능한 모든 계층 탐색 경로 + 각 경로의 시작 root 정보&lt;/b&gt;를 저장한 테이블 생성&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1751005250106&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;hierarchy AS (
  SELECT CONNECT_BY_ROOT employee_id AS root_id,
    employee_id, salary
  FROM employees
  CONNECT BY PRIOR employee_id = manager_id
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n5G0g/btsOVjCV3ZW/ZHjyihlGINl3J36qMdRrxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n5G0g/btsOVjCV3ZW/ZHjyihlGINl3J36qMdRrxK/img.png&quot; data-alt=&quot;hierarchy 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n5G0g/btsOVjCV3ZW/ZHjyihlGINl3J36qMdRrxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn5G0g%2FbtsOVjCV3ZW%2FZHjyihlGINl3J36qMdRrxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;295&quot; height=&quot;351&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;hierarchy 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② 각 직원별로 하위 직원 수 및 예산 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- hierarchy 테이블에서 root_id를 기준으로 총계 계산&lt;/p&gt;
&lt;pre id=&quot;code_1751005337569&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;team_stats AS (
  SELECT root_id AS employee_id,
    COUNT(*) - 1 AS team_size, SUM(salary) AS budget
  FROM hierarchy
  GROUP BY root_id
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (1).png&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5bieH/btsOVX6UJOT/0uRCHvf9vXrlGtCpk1HUYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5bieH/btsOVX6UJOT/0uRCHvf9vXrlGtCpk1HUYk/img.png&quot; data-alt=&quot;team_stats 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5bieH/btsOVX6UJOT/0uRCHvf9vXrlGtCpk1HUYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5bieH%2FbtsOVX6UJOT%2F0uRCHvf9vXrlGtCpk1HUYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;333&quot; height=&quot;249&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (1).png&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;team_stats 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 각 직원의 level 계산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계층형 질의, LEVEL 가상 칼럼 활용&lt;/p&gt;
&lt;pre id=&quot;code_1751005555679&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;levels AS (
  SELECT employee_id, LEVEL AS lvl
  FROM employees
  START WITH manager_id IS NULL
  CONNECT BY PRIOR employee_id = manager_id
)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (2).png&quot; data-origin-width=&quot;243&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1pQKT/btsOUR1iHZH/0AJIehh03SKIgW0tEpDeB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1pQKT/btsOUR1iHZH/0AJIehh03SKIgW0tEpDeB0/img.png&quot; data-alt=&quot;levels 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1pQKT/btsOUR1iHZH/0AJIehh03SKIgW0tEpDeB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1pQKT%2FbtsOUR1iHZH%2F0AJIehh03SKIgW0tEpDeB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;190&quot; height=&quot;255&quot; data-filename=&quot;화면 캡처 2025-06-26 102237 (2).png&quot; data-origin-width=&quot;243&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;levels 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ 최종 쿼리 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- WITH 구문을 통해 위의 3가지 테이블을 사전 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 3가지 테이블을 기존 Employees 테이블을 기준으로 left join하여 최종 쿼리 정답 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- team_size와 budget이 NULL인 최하위 노드들에 대해서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; NVL (또는 COALESCE) 함수를 사용해 각각 0과 자신의 salary 값으로 대체&lt;/p&gt;
&lt;pre id=&quot;code_1751005683272&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH hierarchy AS (
  SELECT CONNECT_BY_ROOT employee_id AS root_id,
    employee_id, salary
  FROM employees
  CONNECT BY PRIOR employee_id = manager_id
),

team_stats AS (
  SELECT root_id AS employee_id,
    COUNT(*) - 1 AS team_size, SUM(salary) AS budget
  FROM hierarchy
  GROUP BY root_id
),

levels AS (
  SELECT employee_id, LEVEL AS lvl
  FROM employees
  START WITH manager_id IS NULL
  CONNECT BY PRIOR employee_id = manager_id
)


SELECT e.employee_id, e.employee_name, l.lvl as &quot;level&quot;,
    NVL(ts.team_size, 0) AS team_size,
    NVL(ts.budget, e.salary) AS budget
FROM employees e
    LEFT JOIN team_stats ts ON e.employee_id = ts.employee_id
    LEFT JOIN levels l ON e.employee_id = l.employee_id
ORDER BY 3, 5 DESC, 2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dC6uJ8/btsOVwhsMJC/xnFPjBMkvniaJhMoooXxI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dC6uJ8/btsOVwhsMJC/xnFPjBMkvniaJhMoooXxI1/img.png&quot; data-alt=&quot;최종 출력 테이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dC6uJ8/btsOVwhsMJC/xnFPjBMkvniaJhMoooXxI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdC6uJ8%2FbtsOVwhsMJC%2FxnFPjBMkvniaJhMoooXxI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;297&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종 출력 테이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Reference&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.naver.com/ilifo_book/223460894842&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/ilifo_book/223460894842&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://infjin.tistory.com/147&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://infjin.tistory.com/147&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mjn5027.tistory.com/55&quot;&gt;https://mjn5027.tistory.com/55&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/173</guid>
      <comments>https://working-helen.tistory.com/173#entry173comment</comments>
      <pubDate>Fri, 27 Jun 2025 15:32:14 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 MySQL Med. ~ Hard</title>
      <link>https://working-helen.tistory.com/172</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL Med. ~ Hard&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3564.&amp;nbsp;Seasonal&amp;nbsp;Sales&amp;nbsp;Analysis&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Find the most popular product category for each season. The popularity of a category is determined by the total quantity sold in that season. If there is a tie, select the category with the highest total revenue (quantity &amp;times; price).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLYslJ/btsOhHYGmzR/PctqDhtRe5Vetvu7LJ3Oyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLYslJ/btsOhHYGmzR/PctqDhtRe5Vetvu7LJ3Oyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLYslJ/btsOhHYGmzR/PctqDhtRe5Vetvu7LJ3Oyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLYslJ%2FbtsOhHYGmzR%2FPctqDhtRe5Vetvu7LJ3Oyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;200&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 : WITH 구문 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- WITH로 여러 임시 쿼리를 생성할 땐 ' , '로 연결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 앞서 생성한 &lt;span style=&quot;text-align: start;&quot;&gt;CTE&lt;/span&gt;를 뒤에 생성한 &lt;span style=&quot;text-align: start;&quot;&gt;CTE&lt;/span&gt;에서 호출 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 반대는 불가능하므로 &lt;span style=&quot;text-align: start;&quot;&gt;CTE&lt;/span&gt; 의존 관계 기준으로 위&amp;rarr;아래로 나열해야 함&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 날짜를 계절로 변환 &amp;rarr; 계절 + 카테고리별 총계 계산 &amp;rarr; 계절별 최대값 확인&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748491665740&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with season as (
    select sale_id, product_id, category, quantity, price,
        case when to_char(sale_date, 'MM') between 3 and 5 then 'Spring'
             when to_char(sale_date, 'MM') between 6 and 8 then 'Summer'
             when to_char(sale_date, 'MM') between 9 and 11 then 'Fall'
             else 'Winter' end as season
    from sales join products using(product_id)
), total as (
    select distinct season, category, sum(quantity) as total_quantity, sum(quantity * price) as total_revenue
    from season
    group by season, category
), ranking as (
    select season, category, total_quantity, total_revenue,
        rank() over (partition by season order by total_quantity desc, total_revenue desc) as rnk
    from total
)

select season, category, total_quantity, total_revenue
from ranking 
where rnk = 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3521.&amp;nbsp;Find&amp;nbsp;Product&amp;nbsp;Recommendation&amp;nbsp;Pairs&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Amazon wants to implement the Customers who bought this also bought... feature based on co-purchase patterns. Identify distinct product pairs frequently purchased together by the same customers (where product1_id &amp;lt; product2_id). For each product pair, determine how many customers purchased both products. A product pair is considered for recommendation if at least 3 different customers have purchased both products.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yUElL/btsOhlBNbUt/yEKEmw1DAh7L0V3k6UzfnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yUElL/btsOhlBNbUt/yEKEmw1DAh7L0V3k6UzfnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yUElL/btsOhlBNbUt/yEKEmw1DAh7L0V3k6UzfnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyUElL%2FbtsOhlBNbUt%2FyEKEmw1DAh7L0V3k6UzfnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;171&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 : WITH 구문 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- frequent pairs만 추출한 CTE 먼저 생성 &amp;rarr; product 정보 join&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748494607147&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with pairs as(
    select p1.product_id as product1_id, p2.product_id as product2_id, count(distinct p1.user_id) as customer_count
    from ProductPurchases p1 join ProductPurchases p2
    on p1.user_id = p2.user_id and p1.product_id &amp;lt; p2.product_id
    group by p1.product_id, p2.product_id
    having count(distinct p1.user_id) &amp;gt;= 3
)

select product1_id, product2_id, p1.category as product1_category, p2.category as product2_category, customer_count
from pairs p left join ProductInfo p1 on p.product1_id = p1.product_id
    left join ProductInfo p2 on p.product2_id = p2.product_id
order by 5 desc, 1, 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3554.&amp;nbsp;Find&amp;nbsp;Category&amp;nbsp;Recommendation&amp;nbsp;Pairs&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Amazon wants to understand shopping patterns across product categories. Write a solution to find all category pairs (where category1 &amp;lt; category2). For each category pair, determine the number of unique customers who purchased products from both categories. A category pair is considered reportable if at least 3 different customers have purchased products from both categories.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OMWLt/btsOhW9S2jd/5NNIt4cGj0ke82zyLG73kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OMWLt/btsOhW9S2jd/5NNIt4cGj0ke82zyLG73kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OMWLt/btsOhW9S2jd/5NNIt4cGj0ke82zyLG73kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOMWLt%2FbtsOhW9S2jd%2F5NNIt4cGj0ke82zyLG73kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;380&quot; height=&quot;187&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 앞선 문제와 달리 id가 아닌 category를 기준으로 그룹화&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;LEAST( )&lt;/b&gt; 함수 : 여러 인자 중에서 가장 작은 값을 반환&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &lt;b&gt;GREATEST( )&lt;/b&gt; 함수 : 여러 인자 중에서 가장 큰 값을 반환 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 하나라도 NULL이 들어가면 결과는 NULL이 됨을 주의해야 함&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748499818572&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LEAST(value1, value2, ..., valueN)
GREATEST(value1, value2, ..., valueN)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1748499619152&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with pairs as(
    select p1.product_id as product1_id, p2.product_id as product2_id, p1.user_id
    from ProductPurchases p1 join ProductPurchases p2
    on p1.user_id = p2.user_id and p1.product_id &amp;lt; p2.product_id
)

select least(p1.category, p2.category) as category1,
        greatest(p1.category, p2.category) as category2, count(distinct p.user_id) as customer_count
from pairs p join ProductInfo p1 on p.product1_id = p1.product_id
    join ProductInfo p2 on p.product2_id = p2.product_id and p1.category != p2.category
group by least(p1.category, p2.category), greatest(p1.category, p2.category)
having count(distinct p.user_id) &amp;gt;= 3
order by 3 desc, 1, 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;262.&amp;nbsp;Trips&amp;nbsp;and&amp;nbsp;Users&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Find the cancellation rate of requests with unbanned users (both client and driver must not be banned) each day between &quot;2013-10-01&quot; and &quot;2013-10-03&quot; with at least one completed trip. Round Cancellation Rate to two decimal points.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;357&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NCp0z/btsOhmO5ghq/kYFPnpkPpu3RkObxcPWUuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NCp0z/btsOhmO5ghq/kYFPnpkPpu3RkObxcPWUuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NCp0z/btsOhmO5ghq/kYFPnpkPpu3RkObxcPWUuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNCp0z%2FbtsOhmO5ghq%2FkYFPnpkPpu3RkObxcPWUuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;156&quot; data-origin-width=&quot;357&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 집계함수 안에 case when ~ then ~ else ~ end 구문 바로 사용해서 계산하기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- JOIN 시 ON절에 바로 AND로 필터링 조건 연결&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 칼럼 별칭 지정 시 띄어쓰기를 포함하려면, 이름을 큰 따옴표 &quot; &quot;로 지정해야 함&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748525582042&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with tmp as (
    select t.*
    from Trips t join Users u1 on t.client_id = u1.users_id and u1.banned = 'No'
                join Users u2 on t.driver_id = u2.users_id and u2.banned = 'No'
    where request_at between '2013-10-01' and '2013-10-03'
)


# avg 사용
select request_at as Day,
    round(avg(case when status != 'completed' then 1 else 0 end), 2) as &quot;Cancellation Rate&quot;
from tmp
group by request_at

# sum + count 사용
select request_at as Day,
    round(sum(case when status != 'completed' then 1 else 0 end) / count(*), 2) as &quot;Cancellation Rate&quot;
from tmp
group by request_at&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3451.&amp;nbsp;Find&amp;nbsp;Invalid&amp;nbsp;IP&amp;nbsp;Addresses&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Find invalid IP addresses. An IPv4 address is invalid if it meets any of these conditions : Contains numbers greater than 255 in any octet, Has leading zeros in any octet (like 01.02.03.04), Has less or more than 4 octets&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;513&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/du9L64/btsOio6uip2/NWHz6BEyRsNSMdaykbQzn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/du9L64/btsOio6uip2/NWHz6BEyRsNSMdaykbQzn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/du9L64/btsOio6uip2/NWHz6BEyRsNSMdaykbQzn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdu9L64%2FbtsOio6uip2%2FNWHz6BEyRsNSMdaykbQzn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;295&quot; height=&quot;374&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;513&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 &amp;gt; 문자열 정규 표현식 활용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748522924294&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 대상 문자열에서 찾을 문자열을 찾아서 반환
# n번째 위치부터 검색해서 m번재로 매칭되는 문자열 반환
regexp_substr(대상, 찾을문자열, n, m)

# 대상 문자열에서 찾을 문자열이 나온 횟수 반환
regexp_count(대상, 찾을문자열)

# 대상 문자열이 찾을 문자열을 포함하고 있는지 여부 반환
regexp_like(대상, 찾을문자열)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1748522696486&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with parts as (
    select ip, regexp_substr(ip, '[^\.]+', 1, 1) as part from logs
    union all
    select ip, regexp_substr(ip, '[^\.]+', 1, 2) as part from logs
    union all
    select ip, regexp_substr(ip, '[^\.]+', 1, 3) as part from logs
    union all
    select ip, regexp_substr(ip, '[^\.]+', 1, 4) as part from logs
)

select ip, count(distinct log_id) as invalid_count
from parts join logs using(ip)
where regexp_count(ip, '\.') != 3 or regexp_like(ip, '(^|\.)(0[0-9]+)') or to_number(part) &amp;gt; 255
group by ip
order by 2 desc, 1 desc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;601.&amp;nbsp;Human&amp;nbsp;Traffic&amp;nbsp;of&amp;nbsp;Stadium&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Display the records with three or more rows with consecutive id's, and the number of people is greater than or equal to 100 for each.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7bpA2/btsOjfnnWjG/VBMlK2YpqUCXzcdC502gE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7bpA2/btsOjfnnWjG/VBMlK2YpqUCXzcdC502gE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7bpA2/btsOjfnnWjG/VBMlK2YpqUCXzcdC502gE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7bpA2%2FbtsOjfnnWjG%2FVBMlK2YpqUCXzcdC502gE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;257&quot; height=&quot;393&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1 :&amp;nbsp;WINDOW 함수 사용&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748523726379&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LAG(num, k) OVER (ORDER BY id)
LEAD(num, k) OVER (ORDER BY id)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt; - 현재 행을 기준으로 k행 이전 / 이후의 num 값을 가져옴 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;- 연속되는 숫자의 처음 or 마지막 or 중간인 경우로 WHERE절 조건&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748523685806&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select id, to_char(visit_date, 'YYYY-MM-DD') as visit_date, people
from (select id, visit_date, people,
            lag(id, 1) over (order by id) as pre1,
            lag(id, 2) over (order by id) as pre2,
            lead(id, 1) over (order by id) as post1,
            lead(id, 2) over (order by id) as post2
    from Stadium where people &amp;gt;= 100) s
where (pre1 = id-1 and pre2 = id-2) or (post1 = id+1 and post2 = id+2)
        or (pre1 = id-1 and post1 = id+1)
order by 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;u&gt;연속된 id는 row_number()와의 차가 일정하게 유지&lt;/u&gt;됨을 활용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- `id - row_number() = ind`가 같은 값이면 연속된 그룹&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 같은 ind 그룹 내 record가 3개 이상인 것만 필터링하면 됨&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748524150013&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with tmp as (
    select id, visit_date, people,
            id - row_number() over (order by id) as ind
    from Stadium
    where people &amp;gt;= 100
)

select id, to_char(visit_date, 'YYYY-MM-DD') as visit_date, people
from tmp
where ind in (select ind from tmp
                group by ind
                having count(distinct id) &amp;gt;= 3)
order by 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/172</guid>
      <comments>https://working-helen.tistory.com/172#entry172comment</comments>
      <pubDate>Mon, 9 Jun 2025 11:35:49 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 MySQL Med.</title>
      <link>https://working-helen.tistory.com/171</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL Med.&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1341.&amp;nbsp;Movie&amp;nbsp;Rating&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Find&amp;nbsp;the&amp;nbsp;name&amp;nbsp;of&amp;nbsp;the&amp;nbsp;user&amp;nbsp;who&amp;nbsp;has&amp;nbsp;rated&amp;nbsp;the&amp;nbsp;greatest&amp;nbsp;number&amp;nbsp;of&amp;nbsp;movies.&amp;nbsp;In&amp;nbsp;case&amp;nbsp;of&amp;nbsp;a&amp;nbsp;tie,&amp;nbsp;return&amp;nbsp;the&amp;nbsp;lexicographically&amp;nbsp;smaller&amp;nbsp;user&amp;nbsp;name.&amp;nbsp;Find&amp;nbsp;the&amp;nbsp;movie&amp;nbsp;name&amp;nbsp;with&amp;nbsp;the&amp;nbsp;highest&amp;nbsp;average&amp;nbsp;rating&amp;nbsp;in&amp;nbsp;February&amp;nbsp;2020.&amp;nbsp;In&amp;nbsp;case&amp;nbsp;of&amp;nbsp;a&amp;nbsp;tie,&amp;nbsp;return&amp;nbsp;the&amp;nbsp;lexicographically&amp;nbsp;smaller&amp;nbsp;movie&amp;nbsp;name.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwdrAf/btsOgNK9cIn/MSInkKu1KYKZYjRH7DUoFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwdrAf/btsOgNK9cIn/MSInkKu1KYKZYjRH7DUoFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwdrAf/btsOgNK9cIn/MSInkKu1KYKZYjRH7DUoFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwdrAf%2FbtsOgNK9cIn%2FMSInkKu1KYKZYjRH7DUoFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;366&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 :&amp;nbsp;&lt;b&gt;ROWNUM&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- where절에서 rownum을 사용하기 위해 서브쿼리로 묶기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 절대적인 행 번호가 아닌 가상의 번호이므로 '&amp;lt;' 연산만 가능&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748409410037&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(select name as results
from (select name, count(*) as rated_num
    from Users u join MovieRating r using(user_id)
    group by user_id, name
    order by 2 desc, 1)
where rownum &amp;lt; 2)
union all
(select title as results
from (select title, avg(rating) as agv_rating
    from Movies m join MovieRating r using(movie_id)
    where to_char(created_at, 'YYYY-MM')= '2020-02'
    group by movie_id, title
    order by 2 desc, 1)
where rownum &amp;lt; 2)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;176.&amp;nbsp;Second&amp;nbsp;Highest&amp;nbsp;Salary&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Find the second highest distinct salary from the Employee table. If there is no second highest salary, return null (return None in Pandas).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;247&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edIIda/btsOeIRCY0A/6257LOqwSpQwt2xWR70rU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edIIda/btsOeIRCY0A/6257LOqwSpQwt2xWR70rU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edIIda/btsOeIRCY0A/6257LOqwSpQwt2xWR70rU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedIIda%2FbtsOeIRCY0A%2F6257LOqwSpQwt2xWR70rU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;204&quot; height=&quot;290&quot; data-origin-width=&quot;247&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- WINDOW 함수 이용 : &lt;span style=&quot;text-align: start;&quot;&gt;DENSE_RANK에서 2등인 salary 추출&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 이때 where rank=2를 만족하는 record가 없으면 빈 테이블이 출력되므로&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; NULL 값이 나오게 하기 위해서는 집계함수를 사용하는 전략 이용&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748401735227&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 집계함수를 사용함으로써 빈 테이블일 경우 NULL로 출력
select max(salary) as SecondHighestSalary
from (select salary, dense_rank() over (order by salary desc) as rank
    from Employee) e
where rank = 2

# 집계함수를 쓰지 않으면 빈 테이블이 출력
select *
from (select salary, dense_rank() over (order by salary desc) as rank
    from Employee) e
where rank = 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 2등 = max보다 작은 것 record들 중 max값&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748401875205&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select max(salary) as SecondHighestSalary
from Employee
where salary &amp;lt; (select max(salary) from Employee)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 3&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt; - ALL/ANY 연산자 + 다중행 서브쿼리 사용 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 2등 = 자신보다 큰 값이 적어도 하나 존재하는 record들 중 max값&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748401929351&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select max(salary) as SecondHighestSalary
from Employee
where salary &amp;lt; any(select salary from Employee)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1070.&amp;nbsp;Product&amp;nbsp;Sales&amp;nbsp;Analysis&amp;nbsp;III&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;:&amp;nbsp;Find&amp;nbsp;all&amp;nbsp;sales&amp;nbsp;that&amp;nbsp;occurred&amp;nbsp;in&amp;nbsp;the&amp;nbsp;first&amp;nbsp;year&amp;nbsp;each&amp;nbsp;product&amp;nbsp;was&amp;nbsp;sold.&amp;nbsp;For&amp;nbsp;each&amp;nbsp;product_id,&amp;nbsp;identify&amp;nbsp;the&amp;nbsp;earliest&amp;nbsp;year&amp;nbsp;it&amp;nbsp;appears&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Sales&amp;nbsp;table.&amp;nbsp;Return&amp;nbsp;all&amp;nbsp;sales&amp;nbsp;entries&amp;nbsp;for&amp;nbsp;that&amp;nbsp;product&amp;nbsp;in&amp;nbsp;that&amp;nbsp;year.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwGhzx/btsOd8QPEQT/m5z0bIKgvEWrOWcPahjBr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwGhzx/btsOd8QPEQT/m5z0bIKgvEWrOWcPahjBr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwGhzx/btsOd8QPEQT/m5z0bIKgvEWrOWcPahjBr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwGhzx%2FbtsOd8QPEQT%2Fm5z0bIKgvEWrOWcPahjBr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;377&quot; height=&quot;301&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;- IN, NOT IN 연산자 + 다중컬럼 서브쿼리 사용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748410826936&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select product_id, year as first_year, quantity, price
from Sales
where (product_id, year) in (select product_id, min(year)
                            from Sales group by product_id)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- EXISTS, NOT EXISTS 연산자 + 연관 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 더 작은 year 값을 가지는 record가 없는 경우 = 가장 작은 year인 경우, not exists 조건 만족하도록&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748410826939&quot; class=&quot;armasm&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select product_id, year as first_year, quantity, price
from Sales s1
where not exists (select 1
                from Sales s2
                where s1.product_id = s2.product_id and s1.year &amp;gt; s2.year)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 3&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ALL/ANY 연산자 + 다중행 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 모든 같은 product_id에 속하는 record의 year보다 작은 경우, ALL 조건 만족하도록&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748410826940&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select product_id, year as first_year, quantity, price
from Sales s1
where s1.year &amp;lt;= all (select s2.year
                from Sales s2
                where s1.product_id = s2.product_id)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 4&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;&lt;u&gt;조건을 만족하는 value만 가지고 있는 table과 inner join&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ON절에 AND를 바로 연결해서 JOIN 과정에서 불필요한 record 제거&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748410826942&quot; class=&quot;armasm&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select s1.product_id, s1.year as first_year, s1.quantity, s1.price
from Sales s1 join (select product_id, min(year) as year
                    from Sales
                    group by product_id) s2 on s1.product_id = s2.product_id and s1.year = s2.year&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;✅&amp;nbsp;&lt;b&gt;WITH문&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 쿼리의 결과에 이름 붙여 저장한 후 이후 쿼리에서 재사용하도록 만든 임시 쿼리(CTE)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 복잡한 서브쿼리를 여러 번 재사용하거나 쿼리 가독성을 높이기 위해 사용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;View와&amp;nbsp;달리&amp;nbsp;DB에&amp;nbsp;영구적으로&amp;nbsp;저장되지&amp;nbsp;않고&amp;nbsp;일시적으로&amp;nbsp;정의&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;u&gt;해당 쿼리가 실행될 때에만 일시적으로 존재&lt;/u&gt;하며,&amp;nbsp;&lt;u&gt;쿼리 내에서만 유효하게 사용 가능&lt;/u&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;CTE(Common Table Expression)&lt;/b&gt; : WITH문에서 사용하는 &lt;b&gt;재사용 가능한 이름 있는 서브쿼리&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748411942302&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;WITH 임시쿼리이름 AS (
    SELECT ..
    FROM ...
    WHERE ...
)

# 여러 임시 쿼리를 생성하는 경우 ,로 연결
WITH 임시쿼리이름1 AS (
    SELECT ..
    FROM ...
    WHERE ...
), 임시쿼리이름2 AS (
    SELECT ..
    FROM ...
    WHERE ...
), ....&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;550.&amp;nbsp;Game&amp;nbsp;Play&amp;nbsp;Analysis&amp;nbsp;IV&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Write a solution to report the fraction of players that logged in again on the day after the day they first logged in, rounded to 2 decimal places. In other words, you need to count the number of players that logged in for at least two consecutive days starting from their first login date, then divide that number by the total number of players.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EPsud/btsOhazbWrB/NKjQIXNKoHLGHYK5ysjq80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EPsud/btsOhazbWrB/NKjQIXNKoHLGHYK5ysjq80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EPsud/btsOhazbWrB/NKjQIXNKoHLGHYK5ysjq80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEPsud%2FbtsOhazbWrB%2FNKjQIXNKoHLGHYK5ysjq80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;463&quot; height=&quot;311&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;&lt;u&gt;조건을 만족하는 value만 가지고 있는 table과 inner join&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; a 테이블에다가 연속해서 접근한 경우일때만 f 테이블 record를 join&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; a = 모든 player_id가 존재, f = 연속해서 접근한 player_id만 존재&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ON절에 AND를 바로 연결해서 JOIN 과정에서 불필요한 record 제거&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748410267376&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select round(count(distinct f.player_id) / count(distinct a.player_id), 2) as fraction
from Activity a left join
        (select player_id, min(event_date) as first_date
        from Activity group by player_id) f
    on a.player_id = f.player_id and a.event_date = f.first_date + 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- WITH문을 사용해 from절에 사용할 서브쿼리 f를 사전에 정의&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748410413275&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with f as (select player_id, min(event_date) as first_date
        from Activity
        group by player_id)

select round(count(distinct f.player_id) / count(distinct a.player_id), 2) as fraction
from Activity a left join f
    on a.player_id = f.player_id and a.event_date = f.first_date + 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3421.&amp;nbsp;Find&amp;nbsp;Students&amp;nbsp;Who&amp;nbsp;Improved&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Find the students who have shown improvement. A student is considered to have shown improvement if they meet both of these conditions : Have taken exams in the same subject on at least two different dates. Their latest score in that subject is higher than their first score. Return the result table ordered by student_id, subject in ascending order. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xANLa/btsOe0ZttP8/FMSagSHpMl4qFJ53RHbhp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xANLa/btsOe0ZttP8/FMSagSHpMl4qFJ53RHbhp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xANLa/btsOe0ZttP8/FMSagSHpMl4qFJ53RHbhp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxANLa%2FbtsOe0ZttP8%2FFMSagSHpMl4qFJ53RHbhp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;481&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 : &lt;b&gt;FIRST_VALUE, LAST_VALUE&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 정렬 순서대로 정해진 범위에서의 처음 값, 마지막 값 출력 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 이때 범위의 default가 처음 ~ 현재행&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; exam_date를 기준으로 오름차순 정렬했기 때문에 first_value는 범위를 그대로 사용해도 되지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &lt;u&gt;last_value는 범위를 지정하지 않을 경우 최대 score값을 가지는 행이 아니라, 항상 현재행이 출력됨&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr; last_value의 범위를 처음(UNBOUNDED PRECEDING) ~ &lt;span style=&quot;text-align: start;&quot;&gt;끝(&lt;/span&gt;UNBOUNDED FOLLOWING)으로 변경&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;rarr; first_value +&lt;span style=&quot;text-align: start;&quot;&gt; 내림차순 정렬 조건으로 바꾸기&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748412023470&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;## from절에 들어갈 서브쿼리가 김 &amp;rarr; WITH문 사용
# last_value의 범위를 변경
with tmp as (
    select distinct student_id, subject,
            first_value(score) over (partition by student_id, subject order by exam_date) as first_score, 
            last_value(score) over (partition by student_id, subject order by exam_date
                rows between unbounded preceding and unbounded following) as latest_score,
            count(*) over (partition by student_id, subject) as tries
    from Scores
)

# first_value 사용하고 정렬 순서를 바꾸기
with tmp as (
    select distinct student_id, subject,
            first_value(score) over (partition by student_id, subject order by exam_date) as first_score, 
            first_value(score) over (partition by student_id, subject order by exam_date desc) as latest_score,
            count(*) over (partition by student_id, subject) as tries
    from Scores
)


select student_id, subject, first_score, latest_score
from tmp
where tries &amp;gt;= 2 and first_score &amp;lt; latest_score
order by student_id, subject&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/171</guid>
      <comments>https://working-helen.tistory.com/171#entry171comment</comments>
      <pubDate>Mon, 2 Jun 2025 12:58:30 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 MySQL Med.</title>
      <link>https://working-helen.tistory.com/170</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL Med.&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1158.&amp;nbsp;Market&amp;nbsp;Analysis&amp;nbsp;I&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;find&amp;nbsp;for&amp;nbsp;each&amp;nbsp;user,&amp;nbsp;the&amp;nbsp;join&amp;nbsp;date&amp;nbsp;and&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;orders&amp;nbsp;they&amp;nbsp;made&amp;nbsp;as&amp;nbsp;a&amp;nbsp;buyer&amp;nbsp;in&amp;nbsp;2019.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKHOjv/btsN89VwhyZ/gaToY98Nqv2xNZj66h0jfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKHOjv/btsN89VwhyZ/gaToY98Nqv2xNZj66h0jfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKHOjv/btsN89VwhyZ/gaToY98Nqv2xNZj66h0jfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKHOjv%2FbtsN89VwhyZ%2FgaToY98Nqv2xNZj66h0jfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;359&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;207&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qlH2C/btsN9Jot898/6d4gPQbtCLfVKdFXQWcM0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qlH2C/btsN9Jot898/6d4gPQbtCLfVKdFXQWcM0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qlH2C/btsN9Jot898/6d4gPQbtCLfVKdFXQWcM0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqlH2C%2FbtsN9Jot898%2F6d4gPQbtCLfVKdFXQWcM0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;356&quot; height=&quot;170&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;207&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; 존재하지 않는 경우도 결과에 포함하여 출력하는 문제&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;u&gt;포함되어야 하는 모든 value를 가지고 있는 Users table을 기준으로 outer&amp;nbsp;&lt;/u&gt;&lt;u&gt;join&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ON절에 AND를 바로 연결해서 JOIN 과정에서 불필요한 record 제거 &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747919919231&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select u.user_id as buyer_id, to_char(u.join_date, 'YYYY-MM-DD') as join_date, count(o.order_date) as orders_in_2019
from Users u left outer join Orders o on u.user_id = o.buyer_id
    and o.order_date between '2019-01-01' and '2019-12-31'
group by u.user_id, u.join_date

select u.user_id as buyer_id, to_char(u.join_date, 'YYYY-MM-DD') as join_date, count(o.order_date) as orders_in_2019
from Users u left outer join Orders o on u.user_id = o.buyer_id
    and to_char(o.order_date, 'YYYY') = 2019
group by u.user_id, u.join_date&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1321.&amp;nbsp;Restaurant&amp;nbsp;Growth&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Compute the moving average of how much the customer paid in a seven days window (i.e., current day + 6 days before). average_amount should be rounded to two decimal places.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chWzSk/btsN94slFEs/Fk7zKq0gypFldDuFKYkCKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chWzSk/btsN94slFEs/Fk7zKq0gypFldDuFKYkCKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chWzSk/btsN94slFEs/Fk7zKq0gypFldDuFKYkCKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchWzSk%2FbtsN94slFEs%2FFk7zKq0gypFldDuFKYkCKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;489&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 : &lt;b&gt;WINDOW 함수 연산 범위 지정&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747921621302&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ROWS|RANGE BETWEEN A AND B&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;A : 시작점 정의 &lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CURRENT ROW : 현재 행부&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;UNBOUNDED PRECEDING : 처음부터(DEFAULT)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;N PRECEDING : N 이전부터&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;B : 마지막 지점 정의&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt; CURRENT ROW : 현재 범위까지(DEFAULT)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt; UNBOUNDED FOLLOWING : 마지막까지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;N FOLLOWING : N 이후까지&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;지정 범위가 테이블을 넘어가는 경우 존재하는 행들까지의 record만 계산에 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- visited_on을 기준으로 내림차순 정렬 후&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; WINDOW 함수로 '현재 행의 6개 이전 ~ 현재 행'까지 집계함수 계산&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;span style=&quot;text-align: start;&quot;&gt;'현재 행의 6개 이전 ~ 현재 행'으로 할 경우 visited_on 값이 중복되지 않지만&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; '&lt;span style=&quot;text-align: start;&quot;&gt;현재 행 ~ &lt;span style=&quot;text-align: start;&quot;&gt;현재 행의 6개 이후'로 할 경우 visited_on의 최댓값이 여러번 출력되기 때문에&lt;br /&gt;&amp;nbsp; WHERE절로 원하는 행만 추출할 수 없게 되어 주의&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747921528803&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select *
from (
    select to_char(visited_on, 'YYYY-MM-DD') as visited_on,
        sum(amount) over (order by visited_on ROWS BETWEEN 6 preceding AND CURRENT ROW) as amount,
        round(avg(amount) over (order by visited_on ROWS BETWEEN 6 preceding AND CURRENT ROW), 2) as average_amount
    from (select visited_on, sum(amount) as amount
        from Customer
        group by visited_on
        order by visited_on) C
    ) c
WHERE visited_on &amp;gt;= (select min(visited_on) + 6 FROM Customer)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;180.&amp;nbsp;Consecutive&amp;nbsp;Numbers&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Find&amp;nbsp;all&amp;nbsp;numbers&amp;nbsp;that&amp;nbsp;appear&amp;nbsp;at&amp;nbsp;least&amp;nbsp;three&amp;nbsp;times&amp;nbsp;consecutively.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;241&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wSyYO/btsOaJwJawm/pocnw7mxKxc6PcOMenHgKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wSyYO/btsOaJwJawm/pocnw7mxKxc6PcOMenHgKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wSyYO/btsOaJwJawm/pocnw7mxKxc6PcOMenHgKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwSyYO%2FbtsOaJwJawm%2Fpocnw7mxKxc6PcOMenHgKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;169&quot; height=&quot;303&quot; data-origin-width=&quot;241&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1 : WINDOW 함수 사용&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748054960387&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LAG(num, k) OVER (ORDER BY id)
LEAD(num, k) OVER (ORDER BY id)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 현재 행을 기준으로 k행 이전 / 이후의 num 값을 가져옴&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- LAG, LEAD의 경우 행이 존재하지 않으면 null 리턴&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748054892316&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct num as ConsecutiveNums
from (select num,
        lag(num, 1) over(order by id) as post1, 
        lag(num, 2) over(order by id) as post2
    from Logs) l
where num = post1 and num = post2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- JOIN에서 ON절에 바로 이어서 AND 연결해 조건 추가하기&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748054898871&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct l1.num as ConsecutiveNums
from Logs l1 join Logs l2 on l1.num = l2.num and l1.id = l2.id-1
    join Logs l3 on l1.num = l3.num and l1.id = l3.id-2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;184.&amp;nbsp;Department&amp;nbsp;Highest&amp;nbsp;Salary&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;find&amp;nbsp;employees&amp;nbsp;who&amp;nbsp;have&amp;nbsp;the&amp;nbsp;highest&amp;nbsp;salary&amp;nbsp;in&amp;nbsp;each&amp;nbsp;of&amp;nbsp;the&amp;nbsp;departments.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdoSwQ/btsN8tNXt6Y/shsMIzCrelC9o7pRAc0Gf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdoSwQ/btsN8tNXt6Y/shsMIzCrelC9o7pRAc0Gf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdoSwQ/btsN8tNXt6Y/shsMIzCrelC9o7pRAc0Gf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdoSwQ%2FbtsN8tNXt6Y%2FshsMIzCrelC9o7pRAc0Gf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;302&quot; height=&quot;461&quot; data-origin-width=&quot;388&quot; data-origin-height=&quot;592&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- IN, NOT IN 연산자 + 다중컬럼 서브쿼리 사용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747922933482&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select d.name as Department, e.name as Employee, e.salary as Salary
from Employee e join Department d on e.departmentId = d.id
where (salary, departmentId) in (select max(salary), departmentId
    from Employee group by departmentId)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- EXISTS, NOT EXISTS 연산자 + 연관 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 더 큰 salary 값을 가지는 record가 없는 경우 = 가장 큰 salary인 경우, not exists 조건 만족하도록&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747922939444&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select d.name as Department, e.name as Employee, e.salary as Salary
from Employee e join Department d on e.departmentId = d.id
where not exists (select 1
    from Employee e2 where e2.departmentId = e.departmentId
    and e2.salary &amp;gt; e.salary)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 3&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ALL/ANY 연산자 + 다중행 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 모든 같은 departmentId에 속하는 record의 salary보다 큰 경우, ALL 조건 만족하도록&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747923191447&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select d.name as Department, e.name as Employee, e.salary as Salary
from Employee e join Department d on e.departmentId = d.id
where salary &amp;gt;= all (select salary
    from Employee e2 where e2.departmentId = e.departmentId)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;585.&amp;nbsp;Investments&amp;nbsp;in&amp;nbsp;2016&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;&amp;nbsp;report&amp;nbsp;the&amp;nbsp;sum&amp;nbsp;of&amp;nbsp;all&amp;nbsp;total&amp;nbsp;investment&amp;nbsp;values&amp;nbsp;in&amp;nbsp;2016&amp;nbsp;tiv_2016,&amp;nbsp;for&amp;nbsp;all&amp;nbsp;policyholders&amp;nbsp;who&amp;nbsp;have&amp;nbsp;the&amp;nbsp;same&amp;nbsp;tiv_2015&amp;nbsp;value&amp;nbsp;as&amp;nbsp;one&amp;nbsp;or&amp;nbsp;more&amp;nbsp;other&amp;nbsp;policyholders,&amp;nbsp;and&amp;nbsp;are&amp;nbsp;not&amp;nbsp;located&amp;nbsp;in&amp;nbsp;the&amp;nbsp;same&amp;nbsp;city&amp;nbsp;as&amp;nbsp;any&amp;nbsp;other&amp;nbsp;policyholder.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;361&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xoe0C/btsObrIuisC/swn8YNfAxQZphqLKkcLXQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xoe0C/btsObrIuisC/swn8YNfAxQZphqLKkcLXQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xoe0C/btsObrIuisC/swn8YNfAxQZphqLKkcLXQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxoe0C%2FbtsObrIuisC%2Fswn8YNfAxQZphqLKkcLXQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;376&quot; height=&quot;286&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- IN, NOT IN 연산자 + 서브쿼리 사용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- GROUP BY + HAVING 절로 필터링&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &lt;span style=&quot;text-align: start;&quot;&gt;(lat, lon)는 여러개 있으면 안되고,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;tiv_2015는 여러개 있도록&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748053499836&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select round(sum(tiv_2016), 2) as tiv_2016
from Insurance
where (lat, lon) not in (select lat, lon from Insurance
                        group by lat, lon
                        having count(pid) &amp;gt; 1)
    and tiv_2015 in (select tiv_2015 from Insurance
                    group by tiv_2015
                    having count(pid) &amp;gt; 1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- EXISTS, NOT EXISTS 연산자 + 연관 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 서브쿼리에서 a.pid != b.pid, a.pid != c.pid 조건 필수&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;(lat, lon)값이 같은 다른 record는 없고,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;tiv_2015 값이 같은 다른 record는 존재하도록&amp;nbsp;&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748053516813&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select round(sum(tiv_2016), 2) as tiv_2016
from Insurance a
where not exists (select 1 from Insurance b
                where a.pid != b.pid and a.lat = b.lat and a.lon = b.lon)
    and exists (select 1 from Insurance c
                where a.pid != c.pid and a.tiv_2015 = c.tiv_2015)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 3&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 인라인뷰 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 필터링에 사용할 값들을 먼저 계산한 집계 테이블 &amp;rarr; WHERE절로 필터링&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748053525117&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select round(sum(tiv_2016), 2) as tiv_2016
from (select tiv_2016,
            count(pid) over (partition by lat, lon) as same_place,
            count(pid) over (partition by tiv_2015) as same_2015
        from Insurance) i
where same_place = 1 and same_2015 &amp;gt; 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/170</guid>
      <comments>https://working-helen.tistory.com/170#entry170comment</comments>
      <pubDate>Mon, 26 May 2025 12:51:48 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 MySQL Med.</title>
      <link>https://working-helen.tistory.com/169</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL Med.&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1934.&amp;nbsp;Confirmation&amp;nbsp;Rate&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;The&amp;nbsp;confirmation&amp;nbsp;rate&amp;nbsp;of&amp;nbsp;a&amp;nbsp;user&amp;nbsp;is&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;'confirmed'&amp;nbsp;messages&amp;nbsp;divided&amp;nbsp;by&amp;nbsp;the&amp;nbsp;total&amp;nbsp;number&amp;nbsp;of&amp;nbsp;requested&amp;nbsp;confirmation&amp;nbsp;messages.&amp;nbsp;The&amp;nbsp;confirmation&amp;nbsp;rate&amp;nbsp;of&amp;nbsp;a&amp;nbsp;user&amp;nbsp;that&amp;nbsp;did&amp;nbsp;not&amp;nbsp;request&amp;nbsp;any&amp;nbsp;confirmation&amp;nbsp;messages&amp;nbsp;is&amp;nbsp;0.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baRUPx/btsN3whZsvF/M1ckf0rKmTxKkliJoYaKAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baRUPx/btsN3whZsvF/M1ckf0rKmTxKkliJoYaKAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baRUPx/btsN3whZsvF/M1ckf0rKmTxKkliJoYaKAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaRUPx%2FbtsN3whZsvF%2FM1ckf0rKmTxKkliJoYaKAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;380&quot; height=&quot;536&quot; data-origin-width=&quot;493&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;b&gt;&amp;gt; 존재하지 않는 경우도 결과에 포함하여 출력하는 문제&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 서브 쿼리로 원하는 정보를 가진 table 생성한 후&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &lt;u&gt;포함되어야 하는 모든 value를 가지고 있는 table과 outer &lt;/u&gt;&lt;u&gt;join&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747618933953&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select user_id, coalesce(round(avg(confirmation), 2), 0) as confirmation_rate
from (select user_id,
            case when c.action = 'confirmed' then 1
                else 0 end as confirmation from Confirmations c) C
    right outer join Signups S using(user_id)
group by user_id&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- &lt;u&gt;원하는 정보를 가진 table&lt;/u&gt; + &lt;u&gt;부족한 정보용 table&lt;/u&gt; 각각 생성한 후 &lt;span style=&quot;text-align: start;&quot;&gt;table union&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747622441394&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(select user_id, round(avg(confirmation), 2) as confirmation_rate
    from (select user_id,
                case when c.action = 'confirmed' then 1
                    else 0 end as confirmation from Confirmations c) C
    group by user_id)
union
(select user_id, 0 as confirmation_rate
    from Signups where user_id not in (select user_id from Confirmations))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1907.&amp;nbsp;Count&amp;nbsp;Salary&amp;nbsp;Categories&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;calculate&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;bank&amp;nbsp;accounts&amp;nbsp;for&amp;nbsp;each&amp;nbsp;salary&amp;nbsp;category.&amp;nbsp;The&amp;nbsp;result&amp;nbsp;table&amp;nbsp;must&amp;nbsp;contain&amp;nbsp;all&amp;nbsp;three&amp;nbsp;categories.&amp;nbsp;If&amp;nbsp;there&amp;nbsp;are&amp;nbsp;no&amp;nbsp;accounts&amp;nbsp;in&amp;nbsp;a&amp;nbsp;category,&amp;nbsp;return&amp;nbsp;0.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;407&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TUCYp/btsN1hUSwtH/rlLEjT0MLhO7wtCPDOfJjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TUCYp/btsN1hUSwtH/rlLEjT0MLhO7wtCPDOfJjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TUCYp/btsN1hUSwtH/rlLEjT0MLhO7wtCPDOfJjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTUCYp%2FbtsN1hUSwtH%2FrlLEjT0MLhO7wtCPDOfJjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;347&quot; height=&quot;390&quot; data-origin-width=&quot;407&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; 존재하지 않는 경우도 결과에 포함하여 출력하는 문제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;u&gt;포함되어야 하는 모든 value를 가지고 있는 dummy table을 직접 생성&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;u&gt;dummy table과의 outer join을 통해 포함되어야 하는 모든 value를 출력&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- Oracle의 경우 from절 생략이 안됨, dummy table 생성 시 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;from dual&lt;/span&gt; 이용&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747617240038&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select d.category, coalesce(a.accounts_count, 0) as accounts_count
from (select 'Low Salary' as category from dual
    	union
    	select 'Average Salary' as category from dual
    	union
    	select 'High Salary' as category from dual) d left outer join
    (select category, count(*) as accounts_count
    from (select (case
                    when income &amp;lt; 20000 then 'Low Salary'
                    when income &amp;lt;= 50000 then 'Average Salary'
                    else 'High Salary'
                    end) as category
        from Accounts) A
    	group by category) a on d.category = a.category&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;span style=&quot;text-align: start;&quot;&gt;원하는 정보를 가진 table = &lt;/span&gt;각각의 value별로 table 생성 후 table union&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- where절을 이용해 각각의 group별로 필터링, count(*)를 이용해 NULL인 경우 0으로 계산되도록&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747622477143&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select 'Low Salary' as category, count(account_id) as accounts_count
	from accounts where income &amp;lt;20000
union 
select 'Average Salary' as category, count(account_id) as accounts_count
	from accounts where income between 20000 and 50000
union
select 'High Salary' as category, count(account_id) as accounts_count
	from accounts where income &amp;gt; 50000;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;602.&amp;nbsp;Friend&amp;nbsp;Requests&amp;nbsp;II:&amp;nbsp;Who&amp;nbsp;Has&amp;nbsp;the&amp;nbsp;Most&amp;nbsp;Friends&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Write a solution to find the people who have the most friends and the most friends number.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MbMwp/btsN3uYMEv7/k0oU75RxPRh8NvEjkZPPSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MbMwp/btsN3uYMEv7/k0oU75RxPRh8NvEjkZPPSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MbMwp/btsN3uYMEv7/k0oU75RxPRh8NvEjkZPPSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMbMwp%2FbtsN3uYMEv7%2Fk0oU75RxPRh8NvEjkZPPSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;353&quot; height=&quot;288&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; Oracle에서 출력 행 수 제한&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 : &lt;b&gt;ROWNUM&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- where절에서 rownum을 사용하기 위해 서브쿼리로 묶기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 절대적인 행 번호가 아닌 가상의 번호이므로 '&amp;lt;' 연산만 가능, '='나 '&amp;gt;' 조건 전달 불가능&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747619532350&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select * from (
    select id, count(*) as num
    from
        (select requester_id as id
        from RequestAccepted
        union all
        select accepter_id as id
        from RequestAccepted) A
    group by id
    order by num desc
    )
where rownum &amp;lt; 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1164.&amp;nbsp;Product&amp;nbsp;Price&amp;nbsp;at&amp;nbsp;a&amp;nbsp;Given&amp;nbsp;Date&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Write a solution to find the prices of all products on 2019-08-16. Assume the price of all products before any change is 10.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U2SOy/btsN2SF5HUq/zYBbkMmo2MRqWJDpfgihsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U2SOy/btsN2SF5HUq/zYBbkMmo2MRqWJDpfgihsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U2SOy/btsN2SF5HUq/zYBbkMmo2MRqWJDpfgihsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU2SOy%2FbtsN2SF5HUq%2FzYBbkMmo2MRqWJDpfgihsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;409&quot; height=&quot;413&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; Oracle에서 출력 행 수 제한&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ROWNUM&lt;/b&gt;을 사용하면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;- where절에서 rownum을 사용하기 위해 서브쿼리로 묶기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;- &lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;'&amp;lt;' 연산으로 하나만 남도록, n개만 남도록도 조절 가능&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747622072984&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM (SELECT product_id
           ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY change_date DESC) AS rn
    FROM Products)
WHERE rn &amp;lt; 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;FIRST_VALUE&lt;/b&gt;를 사용하면&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 서브쿼리로 1번 더 감쌀 필요 없이 바로 한 행만 출력 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 모든 같은 partition 그룹끼리 같은 price값을 가지게 됨 &amp;rarr; &lt;u&gt;distinct로 하나만 남도록&amp;nbsp;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;n개만 남도록 조절하는 건 어려움&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747621892665&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT distinct product_id
       FIRST_VALUE(new_price) OVER (PARTITION BY product_id ORDER BY change_date DESC) AS price
FROM Products;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;gt; 존재하지 않는 경우도 결과에 포함하여 출력하는 문제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 서브 쿼리로 원하는 정보를 가진 table 생성한 후&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;u&gt;포함되어야 하는 모든 value를 가지고 있는 table과 outer&amp;nbsp;&lt;/u&gt;&lt;u&gt;join&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747621742766&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select product_id, coalesce(price, 10) as price
from (select distinct product_id,
        first_value(new_price) over(partition by product_id order by change_date desc) as price
        from Products
        where change_date &amp;lt;= '2019-08-16') a right outer join 
    (select distinct product_id from Products) b using(product_id)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;span style=&quot;text-align: start;&quot;&gt;-&amp;nbsp;&lt;/span&gt;&lt;u&gt;원하는 정보를 가진 table&lt;/u&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;u&gt;부족한 정보용 table&lt;/u&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;각각 생성한 후&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;table union&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1747621813737&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(select distinct product_id,
        first_value(new_price) over(partition by product_id order by change_date desc) as price
    from Products
    where change_date &amp;lt;= '2019-08-16')
union
(select product_id, 10 as price
    from Products
    where product_id not in (select product_id from Products
                             where change_date &amp;lt;= '2019-08-16'))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/169</guid>
      <comments>https://working-helen.tistory.com/169#entry169comment</comments>
      <pubDate>Mon, 19 May 2025 10:28:31 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 MySQL Med.</title>
      <link>https://working-helen.tistory.com/168</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL Med.&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3497.&amp;nbsp;Analyze&amp;nbsp;Subscription&amp;nbsp;Conversion&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: A subscription service wants to analyze user behavior patterns. The company offers a 7-day free trial, after which users can subscribe to a paid plan or cancel. Find users who converted from free trial to paid subscription. Calculate each user's average daily activity duration during their free trial period. Calculate each user's average daily activity duration during their paid subscription period. Return the result table ordered by user_id in ascending order.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnx1Fw/btsNPECEQj3/XmvxUyLaGwtqFKOuD1uH3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnx1Fw/btsNPECEQj3/XmvxUyLaGwtqFKOuD1uH3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnx1Fw/btsNPECEQj3/XmvxUyLaGwtqFKOuD1uH3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcnx1Fw%2FbtsNPECEQj3%2FXmvxUyLaGwtqFKOuD1uH3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;479&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1 : CASE WHEN ELSE END 구문&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 조건에 맞지 않은 행 먼저 필터링 후 집계함수 적용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 집계함수는 자동으로 null 제거하고 계산함을 이용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 이때 null이 아닌 0으로 하면 평균 계산에서 분모가 전체 데이터 수가 되므로 옳지 않음&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746769119161&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select user_id,
    round(avg(case when activity_type = 'free_trial' then activity_duration else null end),2) as trial_avg_duration,
    round(avg(case when activity_type = 'paid' then activity_duration else null end),2) as paid_avg_duration
from UserActivity
where user_id in (select user_id from UserActivity
                    where activity_type = 'paid')
group by user_id
order by user_id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;풀이 2 : DECODE&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;- 위와 동일하게 조건에 맞지 않은 행 먼저 필터링 후 집계함수 적용&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- decode(대상, 값1, 리턴1, 값2, 리턴2, ..., 그외 리턴): 대상이 값n과 일치하면 리턴n, 없으면 그외 리턴 출력&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- `case when 대상 = 값 then 리턴 else 그외 리턴`&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 이 구조는 `decode(대상, 값, 리턴, 그외 리턴)`과 같은 동작&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746771038736&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select user_id,
    round(avg(decode(activity_type, 'free_trial', activity_duration , null)),2) as trial_avg_duration,
    round(avg(decode(activity_type, 'paid', activity_duration, null)),2) as paid_avg_duration
from UserActivity
where user_id in (select user_id from UserActivity
                    where activity_type = 'paid')
group by user_id
order by user_id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 집계함수 적용 후 조건에 맞지 않아 null로 출력되는 행을 제거&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746769130432&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select * from
    (select user_id, 
    round(avg(case activity_type when 'free_trial' then 1.0*activity_duration else null end), 2) as trial_avg_duration,
    round(avg(case activity_type when 'paid' then 1.0*activity_duration else null end), 2) as paid_avg_duration
    from UserActivity 
    group by user_id) T
where paid_avg_duration is not null&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3220.&amp;nbsp;Odd&amp;nbsp;and&amp;nbsp;Even&amp;nbsp;Transactions&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;find&amp;nbsp;the&amp;nbsp;sum&amp;nbsp;of&amp;nbsp;amounts&amp;nbsp;for&amp;nbsp;odd&amp;nbsp;and&amp;nbsp;even&amp;nbsp;transactions&amp;nbsp;for&amp;nbsp;each&amp;nbsp;day.&amp;nbsp;If&amp;nbsp;there&amp;nbsp;are&amp;nbsp;no&amp;nbsp;odd&amp;nbsp;or&amp;nbsp;even&amp;nbsp;transactions&amp;nbsp;for&amp;nbsp;a&amp;nbsp;specific&amp;nbsp;date,&amp;nbsp;display&amp;nbsp;as&amp;nbsp;0.&amp;nbsp;Return&amp;nbsp;the&amp;nbsp;result&amp;nbsp;table&amp;nbsp;ordered&amp;nbsp;by&amp;nbsp;transaction_date&amp;nbsp;in&amp;nbsp;ascending&amp;nbsp;order.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FLtvE/btsNRH5IPqo/arCSOucdmUieKMillMpuEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FLtvE/btsNRH5IPqo/arCSOucdmUieKMillMpuEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FLtvE/btsNRH5IPqo/arCSOucdmUieKMillMpuEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFLtvE%2FbtsNRH5IPqo%2FarCSOucdmUieKMillMpuEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;388&quot; height=&quot;472&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1 : CASE WHEN ELSE END 구문&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746770781204&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select to_char(transaction_date, 'YYYY-MM-DD') as transaction_date,
    sum(case when mod(amount, 2) = 1 then amount else 0 end) as odd_sum,
    sum(case when mod(amount, 2) = 0 then amount else 0 end) as even_sum
from transactions
group by transaction_date
order by transaction_date&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2 : DECODE&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746770807043&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select to_char(transaction_date, 'YYYY-MM-DD') as transaction_date,
    sum(decode(mod(amount, 2), 1, amount, 0)) as odd_sum,
    sum(decode(mod(amount, 2), 0, amount, 0)) as even_sum
from transactions
group by transaction_date
order by transaction_date&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;626.&amp;nbsp;Exchange&amp;nbsp;Seats&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;swap&amp;nbsp;the&amp;nbsp;seat&amp;nbsp;id&amp;nbsp;of&amp;nbsp;every&amp;nbsp;two&amp;nbsp;consecutive&amp;nbsp;students.&amp;nbsp;If&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;students&amp;nbsp;is&amp;nbsp;odd,&amp;nbsp;the&amp;nbsp;id&amp;nbsp;of&amp;nbsp;the&amp;nbsp;last&amp;nbsp;student&amp;nbsp;is&amp;nbsp;not&amp;nbsp;swapped.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bavDPx/btsNP7kfHtr/4pr9I6DuqJ6VkKhyAh89hK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bavDPx/btsNP7kfHtr/4pr9I6DuqJ6VkKhyAh89hK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bavDPx/btsNP7kfHtr/4pr9I6DuqJ6VkKhyAh89hK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbavDPx%2FbtsNP7kfHtr%2F4pr9I6DuqJ6VkKhyAh89hK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;211&quot; height=&quot;427&quot; data-origin-width=&quot;260&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746770323499&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT LAG(col) OVER (ORDER BY col2)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ORDER BY절에서 col2를 기준으로 정렬한 후&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LAG : 이전 행의 col1 값 가져오기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LEAD : 이후 행의 col1 값 가져오기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- coalesce(대상1, 대상2, ...) : 처음으로 null이 아닌 값 리턴&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- NVL(대상, 치환값) : 대상이 null이면 치환값 리턴&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746769985695&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# coalesce 사용
select id, 
    case when mod(id, 2) = 0 then lag(student) over (order by id) 
         else coalesce(lead(student) over (order by id), student) end as student
from Seat
order by id


# nvl 사용
select id, nvl(case when mod(id, 2) = 0 then lag(student) over (order by id)
                ELSE lead(student) over (order by id) END, 
                student
                ) as student
from Seat
order by id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1746770013461&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select id, nullif(case when mod(id, 2) = 0 then lag(student) over (order by id)
                ELSE lead(student) over (order by id) END, 
                student
                ) as student
from Seat
order by id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1204.&amp;nbsp;Last&amp;nbsp;Person&amp;nbsp;to&amp;nbsp;Fit&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Bus&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;There&amp;nbsp;is&amp;nbsp;a&amp;nbsp;queue&amp;nbsp;of&amp;nbsp;people&amp;nbsp;waiting&amp;nbsp;to&amp;nbsp;board&amp;nbsp;a&amp;nbsp;bus.&amp;nbsp;However,&amp;nbsp;the&amp;nbsp;bus&amp;nbsp;has&amp;nbsp;a&amp;nbsp;weight&amp;nbsp;limit&amp;nbsp;of&amp;nbsp;1000&amp;nbsp;kilograms,&amp;nbsp;so&amp;nbsp;there&amp;nbsp;may&amp;nbsp;be&amp;nbsp;some&amp;nbsp;people&amp;nbsp;who&amp;nbsp;cannot&amp;nbsp;board.&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;find&amp;nbsp;the&amp;nbsp;person_name&amp;nbsp;of&amp;nbsp;the&amp;nbsp;last&amp;nbsp;person&amp;nbsp;that&amp;nbsp;can&amp;nbsp;fit&amp;nbsp;on&amp;nbsp;the&amp;nbsp;bus&amp;nbsp;without&amp;nbsp;exceeding&amp;nbsp;the&amp;nbsp;weight&amp;nbsp;limit.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CwERi/btsNSlOBgAq/vWFrMhtHqkeTkarXFGCBdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CwERi/btsNSlOBgAq/vWFrMhtHqkeTkarXFGCBdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CwERi/btsNSlOBgAq/vWFrMhtHqkeTkarXFGCBdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCwERi%2FbtsNSlOBgAq%2FvWFrMhtHqkeTkarXFGCBdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;338&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746771666970&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SUM(col1) OVER (ORDER BY col2)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ORDER&amp;nbsp;BY절에서&amp;nbsp;col2를&amp;nbsp;기준으로&amp;nbsp;정렬한&amp;nbsp;후&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위쪽부터 차례대로 col1의 누적합 계산&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ROWNUM : Oracle에서 출력 행 수 제한&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 현재 출력된 데이터 상태를 기준으로 행 번호 부여&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 절대적인 행 번호가 아닌 가상의 번호이므로 특정 행을 지정할 수 없음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; '&amp;lt;' 연산만 가능, '='나 '&amp;gt;' 조건 전달 불가능&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746771602056&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select person_name
from (select person_name, turn, sum(weight) over(order by turn) as cul_weight
    from Queue
    order by turn desc) Q
where cul_weight &amp;lt;= 1000 and rownum &amp;lt; 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;1045.&amp;nbsp;Customers&amp;nbsp;Who&amp;nbsp;Bought&amp;nbsp;All&amp;nbsp;Products&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&amp;nbsp;Write&amp;nbsp;a&amp;nbsp;solution&amp;nbsp;to&amp;nbsp;report&amp;nbsp;the&amp;nbsp;customer&amp;nbsp;ids&amp;nbsp;from&amp;nbsp;the&amp;nbsp;Customer&amp;nbsp;table&amp;nbsp;that&amp;nbsp;bought&amp;nbsp;all&amp;nbsp;the&amp;nbsp;products&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Product&amp;nbsp;table.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGQ7lQ/btsNQnmWb64/3YKiUtOTvCuxCm1xy7kO9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGQ7lQ/btsNQnmWb64/3YKiUtOTvCuxCm1xy7kO9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGQ7lQ/btsNQnmWb64/3YKiUtOTvCuxCm1xy7kO9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGQ7lQ%2FbtsNQnmWb64%2F3YKiUtOTvCuxCm1xy7kO9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;280&quot; height=&quot;465&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;623&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HAVING절 안에 SELECT 서브쿼리 사용하기&lt;/p&gt;
&lt;pre id=&quot;code_1746772709131&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select customer_id
from Customer
group by customer_id
having count(distinct product_key) = (select count(distinct product_key) from Product)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NOT EXISTS 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- (전체 product_id - 특정 고객이 구매한 product_id) 이 결과가 NOT EXISTS이면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 특정 고객이 전체 product_id를 다 구매한 것이므로&lt;/p&gt;
&lt;pre id=&quot;code_1746772736110&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct customer_id
from Customer C1
where not exists(
    select count(distinct product_key) from Product
    minus
    select count(distinct product_key) from Customer C2 where C2.customer_id = C1.customer_id
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;풀이 3&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- NOT EXISTS 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- product_id NOT IN (특정 고객이 구매한 product_id)를 만족하는 product_id가 NOT EXISTS이면&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 특정 고객이 전체 product_id를 다 구매한 것이므로&lt;/p&gt;
&lt;pre id=&quot;code_1746772877965&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct customer_id
from Customer C1
where not exists(
    select 1 from Product
    where product_key not in (select distinct product_key
                             from Customer C2 where C2.customer_id = C1.customer_id)
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/168</guid>
      <comments>https://working-helen.tistory.com/168#entry168comment</comments>
      <pubDate>Mon, 12 May 2025 16:11:45 +0900</pubDate>
    </item>
    <item>
      <title>[SQL 개념 정리] Database / Phase of DB design / ER model / Relational Model / SQL</title>
      <link>https://working-helen.tistory.com/163</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SQL 구문 연습과 함께 데이터베이스와 관련된 개념적인 부분에 대해 공부해본다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.&amp;nbsp;Database &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 2.&amp;nbsp;Phase&amp;nbsp;of&amp;nbsp;DB&amp;nbsp;design &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. Entity-Relationship Model (ER model)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. Relational Model&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5. SQL&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 1.&amp;nbsp;Database&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1) 등장 배경&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; - Big Data와 Web Scale Computing의 등장으로 대용량 데이터를 효율적으로 관리해야할 필요성이 강화 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 초기 데이터 저장 방식은 File System, 많은 문제점이 존재&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;redundancy : 같은 데이터가 여러 파일에 중복 저장&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;integrity : integrity가 보장되지 않아 무결성 문제에 취약&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;consistency : atomic update가 불가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;concurrent access : 다수 사용자의 동시다발적 접근을 잘 처리하지 못함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터 구조가 프로그램과 밀접하게 연결되어 영향을 받음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터 검색 및 수정이 불편함 &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2) DB의&amp;nbsp;특징&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;minimized redundancy&lt;/b&gt; : 동일한 데이터를 여러 위치에 중복 저장되는 것을 최소화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;integrity&lt;/b&gt; : schema에 integrity constraint를 적용해 데이터의 정확성과 신뢰성을 유지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;consistency&lt;/b&gt; : atomicity(원자성)을 만족하며 data consistency 보장&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;concurrent access&lt;/b&gt; : 다수 사용자의 동시다발적 접근에도 일관성과 정확성 유지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;independence&lt;/b&gt; : DB를 사용하는 프로그램이나 application과 독립적으로 존재&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;권환 부여, 사용자 인증 등을 통해 security 보장&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;직관적이고 이해하기 쉬운 데이터 저장 방식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Big data를 저장 및 처리하기에 용이함&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3) 용어 정리&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwqmWa/btsNBdxjlJA/nP8JOoKo6ftdeIhuApMTq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwqmWa/btsNBdxjlJA/nP8JOoKo6ftdeIhuApMTq1/img.png&quot; data-alt=&quot;출차 : https://www.learncomputerscienceonline.com/how-to-design-database/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwqmWa/btsNBdxjlJA/nP8JOoKo6ftdeIhuApMTq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwqmWa%2FbtsNBdxjlJA%2FnP8JOoKo6ftdeIhuApMTq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;723&quot; height=&quot;302&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출차 : https://www.learncomputerscienceonline.com/how-to-design-database/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 127px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8604%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;data&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1396%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;객체, 이벤트, 현상 등에 대하여, 기록할 만한 가치가 있는 정보&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8604%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Database&amp;nbsp;DB &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1396%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여러 사용자가 공유하고 사용할 목적으로 체계적으로 저장해 둔 데이터 모음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt; persistent data의 통합된 모음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8604%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; DB management system&lt;br /&gt;(DBMS)&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1396%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DB를 효율적으로 사용할 수 있도록 해주는 소프트웨어&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;data를 저장, 처리, 관리하는 프로그램들의 모음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;data에 공동으로 사용되는 작업을 모으고 abstraction만 제공&lt;br /&gt;MySQL, Oracle, PostgreSQL 등의 SQL Server&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8604%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; DB administrator&lt;br /&gt;(DBA)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.1396%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DB 안에서 일어나는 모든 작업을 총괄하는 담당자&lt;br /&gt;DB의 설계, 구축, 유지보수, 보안, 성능 최적화 등을 담당 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* &lt;b&gt;atomicity&lt;/b&gt; (원자성)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 트랜잭션 내의 모든연산은 모두 수행되거나 전혀 수행되지 않아야 한다는 성질&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- DBMS는 원자성을 만족하기 때문에 업데이트 중간에 오류가 발생하면 전체 작업을 완전히 취소함으로써 data consistency 보장&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; *&lt;b&gt; integrity&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- DB에 저장된 데이터가 정확성, 일관성, 신뢰성을 유지한다는 성질&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- DB가&amp;nbsp;정의된 테이블 schema를 위반하는 데이터가 없다는 성질&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- DB에는 현실 세계에서 유효한(적절한) 데이터만 저장될 수 있다는 성질&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* &lt;b&gt;integrity constraint (무결성 제약조건)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;DB가 integrity를 유지하도록 명시적으로 설정하는 규칙 또는 조건&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 새로 들어오는 record가 DB의 테이블 schema에 적합한지 확인하는 조건&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 컴퓨터 속 DB가 현실 세계의 조건에 벗어나지 않는 데이터만 저장하도록 조건 설정&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;span&gt;PK, FK, not null, check, unique, domain 범위 등&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;* &lt;b&gt;independence&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp; &lt;span style=&quot;text-align: left;&quot;&gt;DB를 사용하는 프로그램이나 application과 독립적으로 존재&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;- DB를 사용하는 사용자 application은 DB의 물리적, 논리적 구조의 변화에 영향을 받지 않음&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;physical&amp;nbsp;data&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;independence&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- DB의 물리적 구조가 바뀌어도 사용자 application이나 논리적 스키마에는 영향을 주지 않음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- DB를 사용하는 application은 데이터가 DB에 어떻게 저장되는지 물리적 구조를 알지 못해도 됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;logical data&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;independence&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 데이터의 논리적 스키마가 바뀌어도 사용자 application에는 영향을 주지 않음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 사용자 뷰나 프로그램에서 사용하는 인터페이스는 그대로 유지&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. Phase of DB design &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1)&amp;nbsp;DB&amp;nbsp;구축&amp;nbsp;과정&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Analyze requirements&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: application을 만들기 위해 어떤 데이터가 필요한지, 데이터 간 관계는 무엇인지, 포함해야하는 attribute나 조건은 무엇이 있는지 등을 파악 (DB에 반영해야할 needs 파악)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Sketch table structure&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 대략적인 테이블 종류나 관계를 구상&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Determine characteristics of field&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: filed의 name, type, length, default, constraint 등을 구체적으로 결정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Create tables&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 실제로 테이블을 생성하고, Primary Key 등을 지정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2)&amp;nbsp;Phase&amp;nbsp;of&amp;nbsp;DB&amp;nbsp;design&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UHl7m/btsNz9pb3Bs/Z8bTpzs4KGwYg39sVAOb30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UHl7m/btsNz9pb3Bs/Z8bTpzs4KGwYg39sVAOb30/img.png&quot; data-alt=&quot;출처 : https://www.learncomputerscienceonline.com/how-to-design-database/#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UHl7m/btsNz9pb3Bs/Z8bTpzs4KGwYg39sVAOb30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUHl7m%2FbtsNz9pb3Bs%2FZ8bTpzs4KGwYg39sVAOb30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;369&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://www.learncomputerscienceonline.com/how-to-design-database/#google_vignette&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;conceptual design&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.1395%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- requirements를 분석하고 이를 만족하는 최적의 DB 구조를 표현하는 단계&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- ER model (ER schema / diagram) 사용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;logical design&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.1395%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- conceptual design 결과를 DBMS의 구조에 맞게 변환하는 단계&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- Relational model (relational schema) 사용&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 21.8605%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;physical design&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.1395%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- logical design 결과를 실제 DBMS에 구현하는 단계&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 데이터 저장 방식, 인덱스, 파일 구조 등을 결정 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3)&amp;nbsp;용어&amp;nbsp;정리&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1xq8D/btsNAfiqhCq/ujFaBb3a7vV2ld5L60yIrk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1xq8D/btsNAfiqhCq/ujFaBb3a7vV2ld5L60yIrk/img.webp&quot; data-alt=&quot;출처 : https://examradar.com/relational-model/#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1xq8D/btsNAfiqhCq/ujFaBb3a7vV2ld5L60yIrk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1xq8D%2FbtsNAfiqhCq%2FujFaBb3a7vV2ld5L60yIrk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;182&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://examradar.com/relational-model/#google_vignette&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 85px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;schem&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;a&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DB의 논리적 구조를 설계한 디자인&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt; instance&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특정 시점에 DB에 실제로 저장되어 있는 데이터&lt;br /&gt;instance = row = tuple = record&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt; attribute &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;span style=&quot;text-align: start;&quot;&gt;각 테이블의 데이터가&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;특정 속성이나 특징&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;attribute = column = field&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; domain &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 하나의 attribute가 가질 수 있는 값 범위나 타입 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.8605%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; data&amp;nbsp;model&amp;nbsp; &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 83.1395%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DB의&amp;nbsp;구조를 설명하고 설계하기 위한 이론적 틀이나 표현 방법&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ER model, Relational model, Key-value model 등&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. Entity-Relationship Model (ER model)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1) ER model&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;데이터를&amp;nbsp;entity(개체)와&amp;nbsp;relation(관계)로&amp;nbsp;표현한&amp;nbsp;모델 &lt;br /&gt;-&amp;nbsp;conceptaul&amp;nbsp;design에서&amp;nbsp;사용&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB에 구현해야하는 데이터와 관계를 모두 정의&lt;br /&gt;DB에 포함될 내용의 전반적인 범위를 설정&lt;/li&gt;
&lt;li&gt;ER model의 conceptual schema를 바탕으로 logical design이 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2) ER diagram 구성 요소&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 69px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.7442%; height: 17px;&quot;&gt;Entity&lt;/td&gt;
&lt;td style=&quot;width: 78.2558%; height: 17px;&quot;&gt;고유하게 식별될 수 있고 현실 속에 존재하는 데이터 (객체, 사건, 행동 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.7442%; height: 17px;&quot;&gt;&lt;b&gt;Entity&amp;nbsp;set&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.2558%; height: 17px;&quot;&gt;같은&amp;nbsp;속성을&amp;nbsp;공유하는&amp;nbsp;entity의&amp;nbsp;모음&lt;br /&gt;ER diagram에서 직사각형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.7442%; height: 18px;&quot;&gt;&lt;b&gt;Relationships&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.2558%; height: 18px;&quot;&gt;두&amp;nbsp;개&amp;nbsp;이상의&amp;nbsp;entity&amp;nbsp;사이의&amp;nbsp;연결,&amp;nbsp;entity가&amp;nbsp;어떻게&amp;nbsp;관련되어&amp;nbsp;있는지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.7442%; height: 17px;&quot;&gt;&lt;b&gt;Relationship&amp;nbsp;set&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.2558%; height: 17px;&quot;&gt;같은&amp;nbsp;속성을&amp;nbsp;공유하는&amp;nbsp;relationships의&amp;nbsp;모음,&amp;nbsp;entity&amp;nbsp;set과&amp;nbsp;entity&amp;nbsp;set&amp;nbsp;사이에서&amp;nbsp;형성&lt;br /&gt;ER diagram에서 마름모&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8vLKV/btsNA57mbvj/FMnMEZAiURvQfq46ip2gt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8vLKV/btsNA57mbvj/FMnMEZAiURvQfq46ip2gt1/img.png&quot; data-alt=&quot;출처 : https://www.learncomputerscienceonline.com/entity-relationship-diagram/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8vLKV/btsNA57mbvj/FMnMEZAiURvQfq46ip2gt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8vLKV%2FbtsNA57mbvj%2FFMnMEZAiURvQfq46ip2gt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;234&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://www.learncomputerscienceonline.com/entity-relationship-diagram/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3) Relationship의 특징&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Degree of Relationship set&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.2558%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relationship set이 연결하는 &lt;u&gt;entity set&lt;/u&gt;&lt;u&gt;의 개수&lt;/u&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Relationship cardinality&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.2558%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relationship set에 참여하는 &lt;u&gt;entity &lt;/u&gt;&lt;u&gt;간의 개수 대응 관계&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상대 entity set에서 relationship을 맺는 entity의 개수&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;total participation&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.2558%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;entity set의 모든 entity가 적어도 1번 그 relationship에 참여해야 하는 경우&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.6279%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;weak entity set&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 73.2558%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자체적으로 PK를 가질 수 없는 entity set&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의존하고 있는 strong entity set의 attribute를 함께 사용해야 PK를 가질 수 있음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. Relational Model&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1) Relational Model&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&amp;nbsp;모든&amp;nbsp;데이터를&amp;nbsp;&lt;u&gt;table&amp;nbsp;형태(tabular&amp;nbsp;form)&lt;/u&gt;로&amp;nbsp;표현한&amp;nbsp;모델&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- Relational Model 에 따라 구성된 데이터베이스를 Relational DB라고 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;- logical design에서 사용&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relational schema :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;relation의 이름, attribute(A), 도메인을 정의한 구조/설계도/디자인&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여러&amp;nbsp;relations로 구성된&amp;nbsp;DB의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&gt;elational schema&lt;/span&gt;를 디자인&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;2) Relational shema 구성 요소&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;relation&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이터를 table 형태로 저장한 구조&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relation's&amp;nbsp;degree&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relation의 attribute의 개수 = column의 개수&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relation's&amp;nbsp;cardinality&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relation에 저장된 tuple의 개수 = row의 개수&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Keys&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 75%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;relation에서 각 record를 유일하게 식별하기 위해 사용되는 특정한 attribute들의 조합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;315&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kUHEX/btsNBaHg2zt/ZGsCV7xdyPxJcvhbc7XSG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kUHEX/btsNBaHg2zt/ZGsCV7xdyPxJcvhbc7XSG1/img.png&quot; data-alt=&quot;출처 : https://medium.com/@claire_logan/3-relational-data-model-examples-c9f70c61588c&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kUHEX/btsNBaHg2zt/ZGsCV7xdyPxJcvhbc7XSG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkUHEX%2FbtsNBaHg2zt%2FZGsCV7xdyPxJcvhbc7XSG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;678&quot; height=&quot;271&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;315&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://medium.com/@claire_logan/3-relational-data-model-examples-c9f70c61588c&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3) Keys의 종류&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;super key&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- relation의 각 record를 유일하게 식별하는 attribute들의 조합&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- at most 1 record를 추출하는 attribute 조합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;candidate key&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;최소성을 만족하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/u&gt;&lt;u&gt;super key&lt;/u&gt;, set의 크기가 가장 작은 super key&lt;br /&gt;- subset 중 어느 것도 super key가 될 수 없는 경우&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;primary key&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 대표성을 만족하는 candidate key&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- PK를 구성하는 attribute는 여러 개일 수 있지만, PK 자체는 1개 이하만 가능&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- PK는 자동으로&amp;nbsp;not null + unique constraint를 가짐&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;foreign key&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 다른 relation의 PK를 참조하는 attribute&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Keys 관련 constraint&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;Referential Integrity&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;- FK&lt;/span&gt;&lt;span&gt;가 참조하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;attribute&lt;/span&gt;&lt;span&gt;는 참조 테이블의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PK&lt;/span&gt;&lt;span&gt;여야 함&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;- FK&lt;/span&gt;&lt;span&gt;는 참조되는 테이블의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PK&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;값과 일치하거나&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;이어야 함&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;- FK&lt;/span&gt;&lt;span&gt;가 존재하지 않는&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;유효하지 않은 외부 값을 참조하지 않도록 보장&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;Entity Integrity&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;- PK&lt;/span&gt;&lt;span&gt;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;이 될 수 없고 중복되지 않아야 함&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;각&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;record&lt;/span&gt;&lt;span&gt;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;PK&lt;/span&gt;&lt;span&gt;에 의해 유일하게 식별되어야 함&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;5. SQL&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1)&lt;span&gt;&amp;nbsp;&lt;/span&gt;SQL&amp;nbsp;(Structured&amp;nbsp;Query&amp;nbsp;Language)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;Query&lt;/td&gt;
&lt;td style=&quot;width: 80.5814%;&quot;&gt;DB에서&amp;nbsp;원하는&amp;nbsp;정보를&amp;nbsp;검색하거나&amp;nbsp;조작하기&amp;nbsp;위해&amp;nbsp;사용되는&amp;nbsp;요청문&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;&lt;span&gt;&lt;span&gt;Query language&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.5814%;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;DB&lt;/span&gt;&lt;span&gt;에서 원하는 정보를 조회&lt;/span&gt;&lt;span&gt;하기 위해 사용하는 언어 (&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;request/retrieve)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.4186%;&quot;&gt;&lt;span&gt;&lt;span&gt;DB language&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.5814%;&quot;&gt;&lt;span&gt;&lt;span&gt;DBMS&lt;/span&gt;&lt;span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;DB&lt;/span&gt;&lt;span&gt;를 정의&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;조작&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;관리하는 등에 사용하는 표준 언어&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;SQL은 대표적인 DB language&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 현재 거의 모든 상용 DBMS에서는 SQL을 표준으로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;SQL은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Query language의 기능을 포함하고 있으며, non-procedual query language이자 DB system language&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;MySQL, Oracle, PostgreSQL&lt;span&gt;&amp;nbsp;&lt;/span&gt;등은&lt;span&gt;&amp;nbsp;&lt;/span&gt;SQL 언어를 사용하는 DBMS인 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; DBMS는 회사마다 서로 다르게 존재할 수 있음&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s6PTu/btsNBMzoaMA/X3r9mGRxrgKmWKR8mT1DTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s6PTu/btsNBMzoaMA/X3r9mGRxrgKmWKR8mT1DTk/img.png&quot; data-alt=&quot;출처 : 우재남, 『혼자 공부하는 SQL』, 한빛미디어(2021),p16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s6PTu/btsNBMzoaMA/X3r9mGRxrgKmWKR8mT1DTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs6PTu%2FbtsNBMzoaMA%2FX3r9mGRxrgKmWKR8mT1DTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;314&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 우재남, 『혼자 공부하는 SQL』, 한빛미디어(2021),p16&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) SQL 구문 종류&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 255px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DDL&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- Data Definition language&amp;nbsp;&lt;br /&gt;- 테이블의 구조(schema)를 정의하거나 변경&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- CREATE, ALTER, DROP, TRUNCATE, RENAME&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DML&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;Data Manipulation Language&lt;br /&gt;- 테이블 내 데이터를 조작&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- SELECT, INSERT, UPDATE, DELETE&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;TCL&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;Transaction Control Language&lt;br /&gt;- 트랜잭션의 실행 흐름을 제어&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- COMMIT, ROLLBACK, SAVEPOINT&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DCL&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;Data Control Language&lt;br /&gt;- 사용자 권한 및 접근 제어&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- GRANT, REVOKE&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Reference&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://www.learncomputerscienceonline.com/entity-relationship-diagram/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.learncomputerscienceonline.com/entity-relationship-diagram/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Relational_model&quot;&gt;https://en.wikipedia.org/wiki/Relational_model&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://medium.com/@claire_logan/3-relational-data-model-examples-c9f70c61588c&quot;&gt;https://medium.com/@claire_logan/3-relational-data-model-examples-c9f70c61588c&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/163</guid>
      <comments>https://working-helen.tistory.com/163#entry163comment</comments>
      <pubDate>Mon, 5 May 2025 17:11:17 +0900</pubDate>
    </item>
    <item>
      <title>[코테 연습] Leetcode 코딩테스트 연습 MySQL Easy (3)</title>
      <link>https://working-helen.tistory.com/162</link>
      <description>&lt;h4 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Leetcode 코딩테스트 연습 MySQL Easy&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1633.&amp;nbsp;Percentage&amp;nbsp;of&amp;nbsp;Users&amp;nbsp;Attended&amp;nbsp;a&amp;nbsp;Contest&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;find&amp;nbsp;the&amp;nbsp;percentage&amp;nbsp;of&amp;nbsp;the&amp;nbsp;users&amp;nbsp;registered&amp;nbsp;in&amp;nbsp;each&amp;nbsp;contest&amp;nbsp;rounded&amp;nbsp;to&amp;nbsp;two&amp;nbsp;decimals&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Eh930/btsNzd5a4Zq/42vb2hyGIrPhAfJdsRtLGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Eh930/btsNzd5a4Zq/42vb2hyGIrPhAfJdsRtLGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Eh930/btsNzd5a4Zq/42vb2hyGIrPhAfJdsRtLGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEh930%2FbtsNzd5a4Zq%2F42vb2hyGIrPhAfJdsRtLGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;336&quot; height=&quot;224&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- select 문 내에서 서브쿼리 사용&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745556650563&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select contest_id, round(count(contest_id)/(select count(*) from Users)*100, 2) as percentage
from Register 
group by contest_id
order by 2 desc, 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&amp;nbsp;&lt;b&gt;&amp;gt; count가 0인 조합까지 포함해서 모든 가능한 조합별 개수 세기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- cross join으로 모든 가능한 조합이 포함된 테이블 생성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- left outer join으로 값이 존재하는 조합에 대해서만 열이 추가되도록 (USING 말고 ON절 사용해야 함)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745556650565&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;select tmp.contest_id, round(count(r.user_id)/count(u.user_id)*100, 2) as percentage
from Users u cross join (select distinct contest_id from Register) tmp 
    left outer join Register r on u.user_id = r.user_id and tmp.contest_id = r.contest_id 
group by tmp.contest_id
order by 2 desc, 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1667.&amp;nbsp;Fix&amp;nbsp;Names&amp;nbsp;in&amp;nbsp;a&amp;nbsp;Table&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: Write a solution to fix the names so that only the first character is uppercase and the rest are lowercase. Return the result table ordered by user_id&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/96ABf/btsNy66bGCN/m3RYUyrLrAXgczCVLKM8IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/96ABf/btsNy66bGCN/m3RYUyrLrAXgczCVLKM8IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/96ABf/btsNy66bGCN/m3RYUyrLrAXgczCVLKM8IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F96ABf%2FbtsNy66bGCN%2Fm3RYUyrLrAXgczCVLKM8IK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;331&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;SUBSTR(대상,&amp;nbsp;m,&amp;nbsp;n)&lt;/b&gt;&amp;nbsp;:&amp;nbsp;대상&amp;nbsp;문자열의&amp;nbsp;m&amp;nbsp;위치에서부터&amp;nbsp;n개의&amp;nbsp;문자열&amp;nbsp;추출,&amp;nbsp;n&amp;nbsp;생략시&amp;nbsp;끝까지&amp;nbsp;추출&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;||&lt;/b&gt; : Oracle에서는 문자열 연결 연산자&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745552847816&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select user_id, (upper(substr(name,1,1)) || lower(substr(name,2))) as name
from Users
order by 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1873.&amp;nbsp;Calculate&amp;nbsp;Special&amp;nbsp;Bonus&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;calculate&amp;nbsp;the&amp;nbsp;bonus&amp;nbsp;of&amp;nbsp;each&amp;nbsp;employee.&amp;nbsp;The&amp;nbsp;bonus&amp;nbsp;of&amp;nbsp;an&amp;nbsp;employee&amp;nbsp;is&amp;nbsp;100%&amp;nbsp;of&amp;nbsp;their&amp;nbsp;salary&amp;nbsp;if&amp;nbsp;the&amp;nbsp;ID&amp;nbsp;of&amp;nbsp;the&amp;nbsp;employee&amp;nbsp;is&amp;nbsp;an&amp;nbsp;odd&amp;nbsp;number&amp;nbsp;and&amp;nbsp;the&amp;nbsp;employee's&amp;nbsp;name&amp;nbsp;does&amp;nbsp;not&amp;nbsp;start&amp;nbsp;with&amp;nbsp;the&amp;nbsp;character&amp;nbsp;'M'.&amp;nbsp;The&amp;nbsp;bonus&amp;nbsp;of&amp;nbsp;an&amp;nbsp;employee&amp;nbsp;is&amp;nbsp;0&amp;nbsp;otherwise.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;466&quot; data-origin-height=&quot;531&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KhSND/btsNy9ogQ0V/Zgfzt3gtt74i8keI8MLss0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KhSND/btsNy9ogQ0V/Zgfzt3gtt74i8keI8MLss0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KhSND/btsNy9ogQ0V/Zgfzt3gtt74i8keI8MLss0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKhSND%2FbtsNy9ogQ0V%2FZgfzt3gtt74i8keI8MLss0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;363&quot; height=&quot;414&quot; data-origin-width=&quot;466&quot; data-origin-height=&quot;531&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- MOD(값1, 값2) : Oracle에서 나머지 연산 시 % 대신 MOD 함수를 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- regexp_like(대상, 찾을 문자열) : 찾을 문자열이 포함되어 있는지 true/false 리턴&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745555575980&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select employee_id, case
                when (mod(employee_id, 2) = 1 and not regexp_like(name, '^M')) then salary 
                else 0 end as bonus
from Employees
order by 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- LIKE 연산자 : 문자열 패턴 매칭을 할 때 사용하는 조건절&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; WHERE 절, HAVING 절, CASE WHEN문 안, IF문 안, JOIN 조건 안, CHECK 제약 조건 등에 사용 가능&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745555579903&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select employee_id, case
                when (mod(employee_id, 2) = 1 and name not like 'M%') then salary 
                else 0 end as bonus
from Employees
order by 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3436.&amp;nbsp;Find&amp;nbsp;Valid&amp;nbsp;Emails&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;find&amp;nbsp;all&amp;nbsp;the&amp;nbsp;valid&amp;nbsp;email&amp;nbsp;addresses.&amp;nbsp;It&amp;nbsp;contains&amp;nbsp;exactly&amp;nbsp;one&amp;nbsp;@&amp;nbsp;symbol&amp;nbsp;and&amp;nbsp;ends&amp;nbsp;with&amp;nbsp;'.com'.&amp;nbsp;The&amp;nbsp;part&amp;nbsp;before&amp;nbsp;the&amp;nbsp;@&amp;nbsp;symbol&amp;nbsp;contains&amp;nbsp;only&amp;nbsp;alphanumeric&amp;nbsp;characters&amp;nbsp;and&amp;nbsp;underscores.&amp;nbsp;The&amp;nbsp;part&amp;nbsp;after&amp;nbsp;the&amp;nbsp;@&amp;nbsp;symbol&amp;nbsp;and&amp;nbsp;before&amp;nbsp;.com&amp;nbsp;contains&amp;nbsp;a&amp;nbsp;domain&amp;nbsp;name&amp;nbsp;that&amp;nbsp;contains&amp;nbsp;only&amp;nbsp;letters.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSPIMC/btsNzN6b4aQ/GZTqJp4kSYjHo24BsBV17K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSPIMC/btsNzN6b4aQ/GZTqJp4kSYjHo24BsBV17K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSPIMC/btsNzN6b4aQ/GZTqJp4kSYjHo24BsBV17K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSPIMC%2FbtsNzN6b4aQ%2FGZTqJp4kSYjHo24BsBV17K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;461&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- [ ] 안에서는 각 특수문자에 '\'를 붙히지 않아도 됨, [ ] 밖에서는 특수문자에 '\' 붙히기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- [ ] 안에서는 or 연결끼리 '|'로 연결하지 않아도 됨, [ ] 밖에서는 '|'로 연결 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 각종 정규표현식&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[:alnum:]&amp;nbsp;:&amp;nbsp;알파벳&amp;nbsp;+&amp;nbsp;숫자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[:digit:] : 숫자 0~9&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[:alpha:] : 알파벳 대소문자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[:lower:] : 알파벳 소문자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[:upper:] : 알파벳 대문자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;a-zA-Z0-9 소문자 + 대문자 + 숫자&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1745556384585&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select *
from Users
where regexp_like(email, '^[[:alnum:]_]+@[[:alpha:]]+\.com$')
order by user_id

select *
from Users
where regexp_like(email, '^[a-zA-Z0-9_]+@[a-zA-Z]+\.com$')
order by user_id&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1517.&amp;nbsp;Find&amp;nbsp;Users&amp;nbsp;With&amp;nbsp;Valid&amp;nbsp;E-Mails&lt;/b&gt; &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;:&amp;nbsp;find&amp;nbsp;the&amp;nbsp;users&amp;nbsp;who&amp;nbsp;have&amp;nbsp;valid&amp;nbsp;emails.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N7luH/btsNzAM7OiD/WUeMQibFNgruIZ33J5Yl8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N7luH/btsNzAM7OiD/WUeMQibFNgruIZ33J5Yl8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N7luH/btsNzAM7OiD/WUeMQibFNgruIZ33J5Yl8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN7luH%2FbtsNzAM7OiD%2FWUeMQibFNgruIZ33J5Yl8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;473&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;풀이&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- [ ] 안에서는 각 특수문자에 '\'를 붙히지 않아도 됨,&amp;nbsp;[ ] 밖에서는 특수문자에 '\' 붙히기&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- [ ] 안에서는 or 연결끼리 '|'로 연결하지 않아도 됨, [ ] 밖에서는 '|'로 연결 &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745559442766&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select *
from Users
where regexp_like(mail, '^[[:alpha:]][[:alnum:]_.-]*@leetcode\.com$')

select *
from Users
where regexp_like(mail, '^[A-Za-z][A-Za-z0-9_.-]*@leetcode\.com$')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>외부 수업/SQL 스터디</category>
      <author>HaeWon_Seo</author>
      <guid isPermaLink="true">https://working-helen.tistory.com/162</guid>
      <comments>https://working-helen.tistory.com/162#entry162comment</comments>
      <pubDate>Mon, 28 Apr 2025 15:47:48 +0900</pubDate>
    </item>
  </channel>
</rss>