<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>JY의 기술블로그</title>
    <link>https://jy9892.tistory.com/</link>
    <description>통계학도 기술블로그</description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 20:50:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jy9892</managingEditor>
    <image>
      <title>JY의 기술블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/7459512/attach/899d8e5824d243a5b0c24708966d5f5b</url>
      <link>https://jy9892.tistory.com</link>
    </image>
    <item>
      <title>[SQL/solvesql LV3] 초기 사용자의 친구 관계 찾기</title>
      <link>https://jy9892.tistory.com/19</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/friendship-between-early-users/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://solvesql.com/problems/friendship-between-early-users/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;https://solvesql.com/problems/friendship-between-early-users/&quot; data-ke-align=&quot;alignCenter&quot; data-og-host=&quot;solvesql.com&quot; data-og-source-url=&quot;https://solvesql.com/problems/friendship-between-early-users/&quot; data-og-url=&quot;https://solvesql.com/problems/friendship-between-early-users/&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/friendship-between-early-users/&quot; target=&quot;_blank&quot; data-source-url=&quot;https://solvesql.com/problems/friendship-between-early-users/&quot;&gt;&lt;div class=&quot;og-image&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;https://solvesql.com/problems/friendship-between-early-users/&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;solvesql.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;Facebook 소셜 네트워크 데이터베이스에는 사용자의 정보와 사용자 사이의 친구 관계가 저장되어 있습니다.&lt;br&gt;&lt;br&gt;edges 테이블의 각 행은 두 사용자(user_a_id, user_b_id)가 &lt;b&gt;서로 친구 관계&lt;/b&gt;라는 의미입니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;이 데이터베이스에서 사용자 ID는 &lt;b&gt;auto increment 정수&lt;/b&gt;로 생성되기 때문에, &lt;b&gt;ID가 낮을수록 더 일찍 가입한 사용자&lt;/b&gt;라고 볼 수 있습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;따라서 친구 관계인 두 사용자 ID의 합(user_a_id + user_b_id)이 작을수록 &lt;b&gt;더 초창기에 형성된 친구 관계일 가능성이 높다&lt;/b&gt;고 추측할 수 있습니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  문제 정리&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;테이블&lt;/b&gt;: edges&lt;br&gt;&lt;b&gt;주요 컬럼&lt;/b&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;user_a_id : 친구 관계 사용자 A의 ID&lt;/li&gt;&lt;li&gt;user_b_id : 친구 관계 사용자 B의 ID&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;찾고 싶은 값&lt;/b&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;br&gt;&lt;b&gt;두 사용자 ID의 합(id_sum)이 “상위 0.1%”에 해당하는 모든 친구 관계&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력 컬럼&lt;/b&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;user_a_id&lt;/li&gt;&lt;li&gt;user_b_id&lt;/li&gt;&lt;li&gt;id_sum (= user_a_id + user_b_id)&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  문제 해결 흐름&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;친구 관계 한 줄을 기준으로, 우리는 다음을 계산해야 합니다.&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;845&quot; data-start=&quot;820&quot; data-ke-list-type=&quot;decimal&quot;&gt; 
 &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;각 친구 관계의 &lt;b&gt;id_sum 계산 (&lt;/b&gt;id_sum = user_a_id + user_b_id)&lt;/li&gt; 
 &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;id_sum이 &lt;b&gt;작은 순서대로 정렬&lt;/b&gt;해서 “초기일수록 앞쪽”에 오게 한다.&lt;/li&gt; 
 &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;그 정렬 결과에서 각 관계의 &lt;b&gt;순위(rn)&lt;/b&gt; 를 만든다. (가장 초기 관계가 1등, 다음이 2등 …)&lt;/li&gt; 
 &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;전체 친구 관계 수(&lt;b&gt;total_cnt&lt;/b&gt;)를 구한다.&lt;/li&gt; 
 &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;문제에서 정의한 “상위 %”는 아래와 같다. 
  &lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;&lt;b&gt;상위 % = 순위 / 전체 관계 수&lt;/b&gt;&lt;/li&gt; 
   &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;따라서 “초기 0.1%”는 rn / total_cnt &amp;lt;= 0.001&lt;/li&gt; 
   &lt;li data-end=&quot;845&quot; data-start=&quot;820&quot;&gt;이 조건을 만족하는 친구 관계만 출력하면 된다.&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt; 쿼리&lt;/h3&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;WITH ranked AS (
&amp;nbsp;&amp;nbsp;SELECT
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;user_a_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;user_b_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(user_a_id + user_b_id) AS id_sum,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ROW_NUMBER() OVER (ORDER BY (user_a_id + user_b_id) ASC) AS rn,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COUNT(*) OVER () AS total_cnt
&amp;nbsp;&amp;nbsp;FROM edges
)
SELECT
&amp;nbsp;&amp;nbsp;user_a_id,
&amp;nbsp;&amp;nbsp;user_b_id,
&amp;nbsp;&amp;nbsp;id_sum
FROM ranked
WHERE rn / total_cnt &amp;lt;= 0.001
ORDER BY id_sum ASC, user_a_id, user_b_id&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  핵심 문법 설명&lt;/h2&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) ROW_NUMBER() — 정렬된 결과에 “번호표(순위)” 붙이기&lt;/h3&gt;&lt;div&gt; 
 &lt;div&gt; 
  &lt;div&gt;
   &amp;nbsp;
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;div&gt;
  &lt;span&gt;&lt;span&gt;&lt;span&gt;ROW_NUMBER&lt;/span&gt;&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;&lt;span&gt;OVER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&lt;span&gt;ORDER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;BY&lt;/span&gt;&lt;/span&gt;&lt;span&gt; id_sum &lt;/span&gt;&lt;span&gt;&lt;span&gt;ASC&lt;/span&gt;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;
 &lt;/div&gt; 
&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;ORDER BY id_sum ASC 기준으로 줄 세운 뒤&lt;/li&gt;&lt;li&gt;각 행에 1, 2, 3… 번호를 붙입니다.&lt;/li&gt;&lt;li&gt;즉, rn은 id_sum이 작은 순서 기준 몇 번째인지(순위)를 의미합니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;이 문제에서는 “초기 친구 관계”를 찾으므로&lt;br&gt;id_sum이 작은 관계가 앞 순위가 되도록 ASC를 사용합니다.&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) COUNT(*) OVER() — 전체 행 개수를 모든 행에 붙이기&lt;/h3&gt;&lt;div&gt; 
 &lt;div&gt; 
  &lt;div&gt;
   &amp;nbsp;
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;div&gt;
  &lt;span&gt;&lt;span&gt;&lt;span&gt;COUNT&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;) &lt;/span&gt;&lt;span&gt;&lt;span&gt;OVER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;/span&gt;
 &lt;/div&gt; 
&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;edges 테이블 전체 행 수(=전체 친구 관계 수)를&lt;/li&gt;&lt;li&gt;각 행마다 동일하게 붙입니다.&lt;/li&gt;&lt;li&gt;즉, total_cnt는 “전체 관계 수”입니다.&lt;/li&gt;&lt;/ul&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;3) “상위 0.1%” 조건 구현&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;문제에서 정의한 상위 %:&lt;/p&gt;&lt;blockquote data-end=&quot;2095&quot; data-start=&quot;2074&quot; data-ke-style=&quot;style1&quot;&gt; 
 &lt;p data-end=&quot;2095&quot; data-start=&quot;2076&quot; data-ke-size=&quot;size16&quot;&gt;상위 % = 순위 / 전체 관계 수&lt;/p&gt; 
&lt;/blockquote&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;이를 그대로 SQL로 쓰면:&lt;/p&gt;&lt;div&gt; 
 &lt;div&gt; 
  &lt;div&gt;
   &amp;nbsp;
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;div&gt;
  &lt;span&gt;&lt;span&gt;&lt;span&gt;WHERE&lt;/span&gt;&lt;/span&gt;&lt;span&gt; rn &lt;/span&gt;&lt;span&gt;&lt;span&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt; total_cnt &lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;=&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;0.001&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
 &lt;/div&gt; 
&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;0.001 = 0.1%&lt;/li&gt;&lt;li&gt;“초기 0.1%”에 해당하는 관계만 필터링 됩니다.&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 단순한 SELECT가 아니라 &lt;b&gt;윈도우 함수의 진짜 쓰임새, 순위 기반 퍼센트 필터링 등을 &lt;/b&gt;한 번에 보여주는 좋은 문제 입니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;특히 &lt;b&gt;ROW_NUMBER + COUNT(*) OVER 조합&lt;/b&gt;은 익혀둡시다!!!!&lt;/p&gt;</description>
      <category>SQL</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/19</guid>
      <comments>https://jy9892.tistory.com/19#entry19comment</comments>
      <pubDate>Mon, 22 Dec 2025 21:08:24 +0900</pubDate>
    </item>
    <item>
      <title>[AI역검] 잡다 AI역량검사 약속 정하기 게임 꿀팁 (+무료 연습 게임 공유)</title>
      <link>https://jy9892.tistory.com/18</link>
      <description>&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bffrap/dJMcadHmyhy/Arcl4E5LHKZZNXm3TWnMy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bffrap/dJMcadHmyhy/Arcl4E5LHKZZNXm3TWnMy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bffrap/dJMcadHmyhy/Arcl4E5LHKZZNXm3TWnMy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbffrap%2FdJMcadHmyhy%2FArcl4E5LHKZZNXm3TWnMy1%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;1003&quot; height=&quot;571&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;잡다 AI역량검사&lt;/b&gt; 전략게임 중 하나인 &lt;b&gt;약속 정하기 게임&lt;/b&gt;,&lt;br&gt;너무 어렵죠 ㅠㅠ&lt;br&gt;&amp;nbsp;&lt;br&gt;겉으로 보면 “공통되는 거 하나 고르는 게임 아냐?” 싶은데, 실제로 해보면 &lt;b&gt;기억할 게 많고, 놓치기 쉬운 작업기억 게임&lt;/b&gt;이에요.&lt;br&gt;&amp;nbsp;&lt;br&gt;저도 처음엔 왜 틀렸는지조차 모르겠어서&lt;br&gt;이 게임도 &lt;b&gt;연습용으로 직접 만들어봤습니다.&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;  연습용 게임 링크&lt;br&gt;&lt;a href=&quot;https://v0-memory-game-bugs.vercel.app/&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;b&gt;https://v0-memory-game-bugs.vercel.app/&lt;/b&gt;&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style=&quot;color: #222222;&quot;&gt;(로그인 X, 광고 X, 그냥 바로 연습 가능)&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;약속 정하기 게임?&lt;/h2&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;&lt;b&gt;모두에게 공통으로 해당되는 하나&lt;/b&gt;&lt;/li&gt;&lt;li&gt;또는 &lt;b&gt;아무도 선택하지 않은 하나&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;를 찾아내는 &lt;b&gt;작업기억 기반 전략 게임&lt;/b&gt;입니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;단순 계산 문제가 아니라,&lt;br&gt;&lt;b&gt;작업기억 · 주의집중 · 정보처리 속도&lt;/b&gt;를&lt;br&gt;한꺼번에 보는 인지 과제로 설계돼 있어요.&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  게임 구성&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;총 &lt;b&gt;4라운드&lt;/b&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;b&gt;1~3라운드&lt;/b&gt;: 같은 구조 (공통 요소 찾기)&lt;/li&gt;&lt;li&gt;&lt;b&gt;4라운드&lt;/b&gt;: 완전히 다른 방식 (아무도 선택하지 않은 것 찾기)&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;각 라운드 설명&lt;/h2&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;1️⃣ 1라운드 – 요일 찾기&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;세 사람이 각각 가능한 &lt;b&gt;요일 3~4개&lt;/b&gt; 제시&lt;/li&gt;&lt;li&gt;&lt;b&gt;세 사람 모두에게 공통으로 포함된 요일 1개 선택&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;2️⃣ 2라운드 – 위치 찾기&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;16분할된 지도 위에&lt;/li&gt;&lt;li&gt;각자가 가능한 위치 &lt;b&gt;3~4칸씩 제시&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;세 사람의 위치가 겹치는 단 하나의 칸&lt;/b&gt; 찾기&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;참고&lt;br&gt;제가 만든 연습 게임에는 &lt;b&gt;현재 이 2라운드는 아직 구현하지 않았어요.&lt;/b&gt;&lt;br&gt;(구조가 조금 더 복잡해서 추후 추가 예정…)&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;3️⃣ 3라운드 – 메뉴 선택&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;여러 음식 메뉴가 제시됨&lt;/li&gt;&lt;li&gt;세 사람이 &lt;b&gt;공통으로 선호하는 메뉴 1개&lt;/b&gt; 선택&lt;/li&gt;&lt;/ul&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;4️⃣ 4라운드 – 버스 번호&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;사람들이 각각 탑승하는 &lt;b&gt;버스 번호를 순서대로 제시&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;아무도 탑승하지 않은 버스 번호&lt;/b&gt;를 선택&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;여기서부터는 앞 라운드랑 전략이 완전히 달라집니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;⭐ 핵심 공략: 소거법이 전부다&lt;/h2&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;1·2·3라운드 공통 전략&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;이 게임의 핵심은 &lt;b&gt;교집합만 남기는 소거법&lt;/b&gt;이에요.&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br&gt;순서 정리&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;1️⃣ 첫 번째 사람 정보 3~4개 빠르게 기억&lt;br&gt;2️⃣ 두 번째 사람 정보와 비교&lt;br&gt;→ &lt;b&gt;겹치는 것만 머릿속에 남기고 나머지는 버림&lt;/b&gt;&lt;br&gt;3️⃣ 세 번째 정보와 다시 비교&lt;br&gt;→ 최종 공통 &lt;b&gt;1개만 선택&lt;/b&gt;&lt;br&gt;✔ 많이 외우려고 하면 오히려 망함&lt;br&gt;✔ “남길 것만 남기는 방식”이 정답&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;기억 꿀팁 (실제 체감됨)&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;✔ 요일 / 메뉴 / 위치는&lt;br&gt;→ &lt;b&gt;한 글자 or 간단한 코드&lt;/b&gt;로 치환&lt;br&gt;✔ 속으로 중얼거리면서 기억하면 유지력 ↑&lt;br&gt;✔ 눈으로만 보지 말고 &lt;b&gt;머릿속에서 말로 처리&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&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;/li&gt;&lt;li&gt;피자·파스타 → “피-파”&lt;/li&gt;&lt;/ul&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;4라운드는 전략이 다르다 (중요)&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;버스 번호 라운드는&lt;br&gt;❌ 소거법 X&lt;br&gt;⭕ &lt;b&gt;누적 암기&lt;/b&gt;가 핵심입니다.&lt;br&gt;✔ 번호를 소리 내어 읽거나&lt;br&gt;✔ 리듬 붙여서 외우거나&lt;br&gt;✔ 자기만의 암기 스타일을 활용하는 게 훨씬 좋음&lt;br&gt;  이 라운드는 “빨리 버리는 기억”이 아니라 &lt;b&gt;끝까지 쌓아두는 기억&lt;/b&gt;을 봅니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;잡다 AI역량검사의 &lt;b&gt;약속 정하기 게임&lt;/b&gt;은 센스 게임이 아니라, 불필요한 정보를 버릴 줄 아는지, 필요한 정보만 끝까지 유지할 수 있는지를 보는 문제라고 생각해요.&lt;br&gt;&amp;nbsp;&lt;br&gt;고양이 술래잡기 게임이 메타인지를 본다면,&lt;br&gt;이 게임은 &lt;b&gt;정통 작업기억 게임&lt;/b&gt;에 가깝습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;실전 전에 감이라도 잡고 들어가고 싶다면,&lt;br&gt;연습용으로 한 번쯤 해보는 것도 추천드려요.&lt;br&gt;&amp;nbsp;&lt;br&gt;취준생 여러분 파이팅입니다  &lt;br&gt;다음 게임도 또 정리해볼게요!!&lt;br&gt;&amp;nbsp;&lt;br&gt;(글값은 좋아요, 구독으로 부탁드립니당)&lt;/p&gt;</description>
      <category>바이브코딩</category>
      <category>AI신역검</category>
      <category>AI역검</category>
      <category>AI역검 약속정하기 게임 꿀팁</category>
      <category>신역검</category>
      <category>약속정하기</category>
      <category>약속정하기게임</category>
      <category>역검게임꿀팁</category>
      <category>잡다</category>
      <category>잡다게임</category>
      <category>잡다역검게임</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/18</guid>
      <comments>https://jy9892.tistory.com/18#entry18comment</comments>
      <pubDate>Mon, 22 Dec 2025 00:02:58 +0900</pubDate>
    </item>
    <item>
      <title>[AI역검] 잡다 AI역량검사 고양이 술래잡기 게임 꿀팁 (+무료 연습 게임 공유)</title>
      <link>https://jy9892.tistory.com/17</link>
      <description>&lt;p data-end=&quot;267&quot; data-start=&quot;170&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b17ZX6/dJMcabbKr4a/bWNsQbAK1Yvv6rLCLDrSZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b17ZX6/dJMcabbKr4a/bWNsQbAK1Yvv6rLCLDrSZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b17ZX6/dJMcabbKr4a/bWNsQbAK1Yvv6rLCLDrSZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb17ZX6%2FdJMcabbKr4a%2FbWNsQbAK1Yvv6rLCLDrSZK%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;1011&quot; height=&quot;573&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;267&quot; data-start=&quot;170&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;267&quot; data-start=&quot;170&quot; data-ke-size=&quot;size16&quot;&gt;요즘 &lt;b&gt;잡다 AI역량검사&lt;/b&gt; 준비하시는 분들 많죠?&lt;br /&gt;저도 취업 준비하면서 잡다 역검을 보게 됐는데&lt;/p&gt;
&lt;p data-end=&quot;267&quot; data-start=&quot;170&quot; data-ke-size=&quot;size16&quot;&gt;그중에서도 유독 &lt;b&gt;고양이 술래잡기 게임&lt;/b&gt;이 너무 어렵더라고요.&lt;/p&gt;
&lt;p data-end=&quot;267&quot; data-start=&quot;170&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;솔직히 말하면&amp;hellip;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;처음엔 내가 이렇게 기억력이 안 좋았나?&lt;/b&gt; 싶을 정도로 계속 틀렸어요  &lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;그래서 &amp;ldquo;이거 연습이라도 해보자&amp;rdquo; 싶어서&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;바이브코딩으로 &lt;b&gt;직접 연습용 게임을 만들어버렸습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;해당 게임을 너무 못해서 이것만 연습하고 싶었는데.. 실제 연습 환경은 너무 답답하더라고요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;367&quot; data-start=&quot;249&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;249&quot;&gt;연습 기회는 몇 번 안 주어지고&lt;/li&gt;
&lt;li data-end=&quot;300&quot; data-start=&quot;271&quot;&gt;한 번 하려고 들어가면 바로 실전처럼 진행되고&lt;/li&gt;
&lt;li data-end=&quot;336&quot; data-start=&quot;301&quot;&gt;&lt;b&gt;내가 뭐가 맞았고 뭐가 틀렸는지 결과도 제대로 못 봄&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;367&quot; data-start=&quot;337&quot;&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;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;a href=&quot;https://v0-cat-mouse-game.vercel.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://v0-cat-mouse-game.vercel.app/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;486&quot; data-start=&quot;381&quot; data-ke-size=&quot;size16&quot;&gt;(로그인 X, 광고 X, 그냥 바로 연습 가능)&lt;/p&gt;
&lt;p data-end=&quot;486&quot; data-start=&quot;381&quot; 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;h2 data-end=&quot;523&quot; data-start=&quot;493&quot; data-ke-size=&quot;size26&quot;&gt;잡다 AI역량검사 고양이 술래잡기 게임이 뭐냐면요....&lt;/h2&gt;
&lt;p data-end=&quot;591&quot; data-start=&quot;525&quot; data-ke-size=&quot;size16&quot;&gt;이 게임은 단순한 기억력 테스트가 아니고,&lt;/p&gt;
&lt;p data-end=&quot;591&quot; data-start=&quot;525&quot; data-ke-size=&quot;size16&quot;&gt;기억 + 판단 + 확신 정도(메타인지)를 동시에 보는 게임이에요.&lt;/p&gt;
&lt;h3 data-end=&quot;613&quot; data-start=&quot;593&quot; data-ke-size=&quot;size23&quot;&gt;  기본 구조&amp;nbsp;&lt;/h3&gt;
&lt;p data-end=&quot;640&quot; data-start=&quot;615&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6&amp;times;6 판, 총 36칸&lt;/b&gt;에서 진행됩니다.&lt;/p&gt;
&lt;h4 data-end=&quot;665&quot; data-start=&quot;642&quot; data-ke-size=&quot;size20&quot;&gt;1️⃣ 화면 1 &amp;ndash; 쥐 위치 기억&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;747&quot; data-start=&quot;666&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;702&quot; data-start=&quot;666&quot;&gt;6&amp;times;6 판 위에 &lt;b&gt;여러 마리 쥐가 아주 짧은 시간&lt;/b&gt; 나타남&lt;/li&gt;
&lt;li data-end=&quot;747&quot; data-start=&quot;703&quot;&gt;순식간에 사라짐&lt;br /&gt;  이때 &lt;b&gt;쥐의 정확한 위치를 최대한 기억&lt;/b&gt;해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;771&quot; data-start=&quot;749&quot; data-ke-size=&quot;size20&quot;&gt;2️⃣ 화면 2 &amp;ndash; 고양이 등장&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;830&quot; data-start=&quot;772&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;796&quot; data-start=&quot;772&quot;&gt;같은 6&amp;times;6 판에 &lt;b&gt;고양이들이 등장&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;830&quot; data-start=&quot;797&quot;&gt;고양이는 &lt;b&gt;파란 고양이 / 빨간 고양이&lt;/b&gt;로 색이 나뉨&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;846&quot; data-start=&quot;832&quot; data-ke-size=&quot;size20&quot;&gt;3️⃣ 판단 규칙&lt;/h4&gt;
&lt;p data-end=&quot;883&quot; data-start=&quot;847&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;이전에 쥐가 있던 칸 위에 고양이가 있으면 = 잡았다&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;910&quot; data-start=&quot;885&quot; data-ke-size=&quot;size16&quot;&gt;그래서 매 라운드마다 다음을 판단해야 합니다.&lt;/p&gt;
&lt;p data-end=&quot;910&quot; data-start=&quot;885&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;941&quot; data-start=&quot;917&quot; data-ke-size=&quot;size26&quot;&gt;응답 방식 (여기서 멘탈 많이 털림&amp;hellip;)&lt;/h2&gt;
&lt;p data-end=&quot;971&quot; data-start=&quot;943&quot; data-ke-size=&quot;size16&quot;&gt;각 화면 세트마다 총 2&lt;b&gt;가지 선택&lt;/b&gt;을 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1072&quot; data-start=&quot;973&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1001&quot; data-start=&quot;973&quot;&gt;파란 고양이가 쥐를 잡았는지 여부 (O / X) + 그 판단에 대한 &lt;b&gt;확신 정도&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1051&quot; data-start=&quot;1023&quot;&gt;빨간 고양이가 쥐를 잡았는지 여부 (O / X) + 그 판단에 대한 &lt;b&gt;확신 정도&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1085&quot; data-start=&quot;1074&quot; data-ke-size=&quot;size16&quot;&gt;  확신 단계는 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;전혀 확신 없음 ~ 매우 확신 &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;같은 식으로 선택하게 돼요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1085&quot; data-start=&quot;1074&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2093&quot; data-start=&quot;2070&quot; data-ke-size=&quot;size26&quot;&gt;잡다 역검 고양이 술래잡기 꿀팁 정리&lt;/h2&gt;
&lt;p data-end=&quot;2258&quot; data-start=&quot;2111&quot; data-ke-size=&quot;size16&quot;&gt;✔ 쥐 위치를 &lt;b&gt;모두 완벽히 외우려고 하지 말기&lt;/b&gt;&lt;br /&gt;✔ 겹치는 위치 위주로 기억 전략 세우기&lt;br /&gt;✔ 헷갈리면 &lt;b&gt;확신 낮게 주는 연습&lt;/b&gt;이 중요&lt;br /&gt;✔ 무조건 자신감 MAX는 오히려 독&lt;br /&gt;✔ 연습을 통해 &lt;b&gt;내가 헷갈리는 구간을 스스로 인지하는 게 핵심&lt;/b&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-end=&quot;727&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;솔직히 잡다 역검 보면서&lt;/p&gt;
&lt;p data-end=&quot;727&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이거 연습 좀 더 해보고 들어갔으면&amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;727&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;생각 한 번쯤 다들 하셨을 거예요.&lt;/p&gt;
&lt;p data-end=&quot;799&quot; data-start=&quot;729&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;799&quot; data-start=&quot;729&quot; data-ke-size=&quot;size16&quot;&gt;저도 그 답답함 때문에 이 게임을 직접 만들어서&lt;/p&gt;
&lt;p data-end=&quot;799&quot; data-start=&quot;729&quot; data-ke-size=&quot;size16&quot;&gt;계속 틀려보고, 계속 헷갈려보고, 확신을 조절하는 연습을 했습니다.&lt;/p&gt;
&lt;p data-end=&quot;866&quot; data-start=&quot;801&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;866&quot; data-start=&quot;801&quot; data-ke-size=&quot;size16&quot;&gt;완벽하게 맞추려고 하지 말고,&lt;/p&gt;
&lt;p data-end=&quot;866&quot; data-start=&quot;801&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 헷갈리는 순간을 인지하는 연습 &lt;/b&gt;그게 이 게임의 핵심이라고 생각해요.&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;필요한 분들은 부담 없이 연습용으로 써보세요.&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;취준생 여러분 진짜 파이팅입니다!!!!!!!!!!!!!!&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;(글값은 좋아요, 구독으로 부탁드립니당)&lt;/p&gt;</description>
      <category>바이브코딩</category>
      <category>AI역검</category>
      <category>게임연습</category>
      <category>고양이술래잡기</category>
      <category>메타인지</category>
      <category>잡다</category>
      <category>잡다게임연습</category>
      <category>잡다역검</category>
      <category>잡다연습</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/17</guid>
      <comments>https://jy9892.tistory.com/17#entry17comment</comments>
      <pubDate>Fri, 19 Dec 2025 17:57:23 +0900</pubDate>
    </item>
    <item>
      <title>[SQL/solvesql LV2] 이틀 연속 미세먼지가 나빠진 날</title>
      <link>https://jy9892.tistory.com/16</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/bad-finddust-days-in-a-row/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://solvesql.com/problems/bad-finddust-days-in-a-row/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;https://solvesql.com/problems/bad-finddust-days-in-a-row/&quot; data-ke-align=&quot;alignCenter&quot; data-og-host=&quot;solvesql.com&quot; data-og-source-url=&quot;https://solvesql.com/problems/bad-finddust-days-in-a-row/&quot; data-og-url=&quot;https://solvesql.com/problems/bad-finddust-days-in-a-row/&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/bad-finddust-days-in-a-row/&quot; target=&quot;_blank&quot; data-source-url=&quot;https://solvesql.com/problems/bad-finddust-days-in-a-row/&quot;&gt;&lt;div class=&quot;og-image&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;https://solvesql.com/problems/bad-finddust-days-in-a-row/&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;solvesql.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;서울숲 일별 평균 대기오염도 데이터베이스에는 2022년 동안 매일 기록된 &lt;b&gt;미세먼지&lt;/b&gt;정보가 저장되어 있습니다.&lt;br&gt;&lt;br&gt;우리가 궁금한 건 단순히 미세먼지 농도가 높은 날이 아니라, &lt;b&gt;이틀 연속 미세먼지 수치가 나빠져서, 세 번째 날에 30㎍/㎥ 이상이 된 날&lt;/b&gt;을 찾아내는 것입니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;예를 들어,&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;1월 3일: 28㎍/㎥&lt;/li&gt;&lt;li&gt;1월 4일: 37㎍/㎥&lt;/li&gt;&lt;li&gt;1월 5일: 52㎍/㎥&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;이라면,&lt;br&gt;&lt;br&gt;&lt;b&gt;3→4, 4→5 이틀 연속 미세먼지가 상승했고, 1월 5일 수치가 30 이상&lt;/b&gt;이므로 &lt;b&gt;1월 5일이 우리가 찾는 경고 일자(date_alert)&lt;/b&gt;가 됩니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;  문제 정리&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;테이블: measurements&lt;br&gt;&lt;br&gt;주요 컬럼:&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;measured_at : 날짜 (일자)&lt;/li&gt;&lt;li&gt;pm10 : 해당 날짜의 일 평균 미세먼지 농도(㎍/㎥)&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;찾고 싶은 값:&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;date_alert :&lt;/li&gt;&lt;li&gt;&lt;b&gt;이틀 연속 미세먼지 수치가 나빠져 세 번째 날(pm10)이 30㎍/㎥ 이상이 된 날짜&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;  문제 해결 흐름&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 날짜를 D라고 할 때,&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;D-2일, D-1일, D일 이렇게 &lt;b&gt;3일을 한 세트&lt;/b&gt;로 보고,&lt;/li&gt;&lt;li&gt;조건은 아래와 같습니다.&lt;/li&gt;&lt;/ul&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;909&quot; data-start=&quot;793&quot; data-ke-list-type=&quot;decimal&quot;&gt; 
 &lt;li data-end=&quot;859&quot; data-start=&quot;793&quot;&gt;&lt;b&gt;연속 3일 동안 미세먼지가 계속 증가&lt;/b&gt; 
  &lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;859&quot; data-start=&quot;824&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li data-end=&quot;859&quot; data-start=&quot;824&quot;&gt;pm10(D-2) &amp;lt; pm10(D-1) &amp;lt; pm10(D)&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li data-end=&quot;909&quot; data-start=&quot;860&quot;&gt;&lt;b&gt;마지막 날(D)의 미세먼지가 30 이상&lt;/b&gt; 
  &lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;909&quot; data-start=&quot;892&quot; data-ke-list-type=&quot;disc&quot;&gt; 
   &lt;li data-end=&quot;909&quot; data-start=&quot;892&quot;&gt;pm10(D) &amp;gt;= 30&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ol&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;이 조건을 만족하는 날 D를 date_alert로 뽑으면 됩니다.&lt;br&gt;&lt;br&gt;이걸 SQL로 구현하는 가장 자연스러운 방법이 바로 &lt;b&gt;윈도우 함수 LAG를 이용해서 전날·이틀 전 값을 같이 조회하는 것&lt;/b&gt;입니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt; 쿼리&lt;/h3&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;WITH pm AS (
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELECT
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;measured_at,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pm10,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LAG(pm10, 1) OVER (ORDER BY measured_at) AS pm_d1,&amp;nbsp;&amp;nbsp; -- 전날
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LAG(pm10, 2) OVER (ORDER BY measured_at) AS pm_d2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- 이틀 전
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FROM measurements
)
SELECT
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;measured_at AS date_alert
FROM pm
WHERE pm10 &amp;gt;= 30&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- 오늘 수치 30 이상
&amp;nbsp;&amp;nbsp;AND pm_d2 &amp;lt; pm_d1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-- 이틀 전 &amp;lt; 전날
&amp;nbsp;&amp;nbsp;AND pm_d1 &amp;lt; pm10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- 전날 &amp;lt; 오늘 → 3일 연속 상승
ORDER BY date_alert&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt; 핵심 문법 설명&lt;/h3&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. LAG 함수 — 이전 행의 값을 가져오는 윈도 함수&lt;/h4&gt;&lt;div&gt; 
 &lt;div&gt; 
  &lt;pre id=&quot;code_1765116848218&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LAG(컬럼명, 몇칸_전) OVER (ORDER BY 정렬기준)&lt;/code&gt;&lt;/pre&gt; 
 &lt;/div&gt; 
&lt;/div&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;예를 들어 LAG(pm10, 1) OVER (ORDER BY measured_at) 라는 뜻은 measured_at 날짜 순서대로 정렬해서, 한 칸 앞(전날)의 pm10 값을 가져오는 것입니다. &lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;div&gt; 
 &lt;div&gt; 
  &lt;div&gt;
   &amp;nbsp;
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;div&gt;
  &lt;span&gt;&lt;span&gt;&lt;span&gt;LAG&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(pm10, &lt;/span&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&lt;span&gt;OVER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&lt;span&gt;ORDER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;BY&lt;/span&gt;&lt;/span&gt;&lt;span&gt; measured_at) &lt;/span&gt;&lt;span&gt;&lt;span&gt;AS&lt;/span&gt;&lt;/span&gt;&lt;span&gt; pm_d1 &lt;/span&gt;&lt;/span&gt;
 &lt;/div&gt; 
 &lt;div&gt;
  &lt;span&gt;&lt;span&gt;&lt;span&gt;LAG&lt;/span&gt;&lt;/span&gt;&lt;span&gt;(pm10, &lt;/span&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;&lt;span&gt;OVER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&lt;span&gt;ORDER&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;BY&lt;/span&gt;&lt;/span&gt;&lt;span&gt; measured_at) &lt;/span&gt;&lt;span&gt;&lt;span&gt;AS&lt;/span&gt;&lt;/span&gt;&lt;span&gt; pm_d2 &lt;/span&gt;&lt;/span&gt;
 &lt;/div&gt; 
&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;LAG(column, offset)는 &lt;b&gt;현재 행 기준 이전 행의 값을 가져오는 함수&lt;/b&gt;입니다.&lt;/li&gt;&lt;li&gt;offset = 1이면 전날, offset = 2이면 이틀 전 데이터를 읽어올 수 있습니다.&lt;/li&gt;&lt;li&gt;OVER (ORDER BY measured_at)&lt;br&gt;→ 날짜순으로 나열된 상태에서 이전 값을 가져오라는 의미입니다.&lt;/li&gt;&lt;/ul&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;이 문제의 핵심은 &lt;b&gt;3일 연속 미세먼지 증가 여부&lt;/b&gt;를 판단하는 것입니다. 따라서 이전 날짜의 pm10 값을 같은 행에서 비교하기 위해 LAG 함수가 사용됩니다.&lt;/p&gt;</description>
      <category>SQL</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/16</guid>
      <comments>https://jy9892.tistory.com/16#entry16comment</comments>
      <pubDate>Sun, 7 Dec 2025 23:19:32 +0900</pubDate>
    </item>
    <item>
      <title>[SQL/solvesql LV4] 세 명이 서로 친구인 관계 찾기</title>
      <link>https://jy9892.tistory.com/15</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/friend-group-of-3/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://solvesql.com/problems/friend-group-of-3/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1742474438202&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://solvesql.com/problems/friend-group-of-3/&quot; data-og-description=&quot;&quot; data-og-host=&quot;solvesql.com&quot; data-og-source-url=&quot;https://solvesql.com/problems/friend-group-of-3/&quot; data-og-url=&quot;https://solvesql.com/problems/friend-group-of-3/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/friend-group-of-3/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://solvesql.com/problems/friend-group-of-3/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://solvesql.com/problems/friend-group-of-3/&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;solvesql.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;  문제 상황&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;소셜 네트워크 데이터를 분석하는 과정에서, 세 명의 사용자가 서로 친구 관계를 맺고 있는 &lt;b&gt;&quot;삼각형 구조&quot;&lt;/b&gt;를 찾아야 합니다. 주어진 &lt;/span&gt;&lt;span&gt;edges&lt;/span&gt;&lt;span&gt; 테이블에는 (A, B) 형태의 친구 관계만 저장되어 있습니다.&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&gt;우리의 목표는:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;두 단계를 거쳐 &lt;b&gt;(A, B, C) 형태의 친구 관계&lt;/b&gt;를 찾고,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;최종적으로&lt;b&gt; (A, C) 관계까지 확인&lt;/b&gt;하여 실제 &lt;b&gt;삼각관계를 필터링&lt;/b&gt;하는 것입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;특정 사용자(예: &lt;/span&gt;&lt;span&gt;3820&lt;/span&gt;&lt;span&gt;)가 포함된 삼각형만 출력합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h3 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;  문제 해결 흐름&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Step 1: A-B-C 관계 찾기&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;edges&lt;/span&gt;&lt;span&gt; 테이블을 두 번 조인하여 &lt;/span&gt;&lt;span&gt;(A &amp;rarr; B &amp;rarr; C)&lt;/span&gt;&lt;span&gt; 관계를 생성합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;E1.user_a_id&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;E1.user_b_id&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;E2.user_b_id&lt;/span&gt;&lt;span&gt; 순서로 친구 연결을 확장합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;결과적으로 &lt;/span&gt;&lt;span&gt;(A, B, C)&lt;/span&gt;&lt;span&gt; 형태의 데이터셋을 만듭니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 하면 &lt;/span&gt;&lt;span&gt;user_a_id &amp;rarr; user_b_id &amp;rarr; user_c_id&lt;/span&gt;&lt;span&gt; 연결 구조가 만들어집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Step 2: A-C 관계 확인&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 &lt;/span&gt;&lt;span&gt;(A, C)&lt;/span&gt;&lt;span&gt; 관계가 실제로 존재하는지 검증해야 합니다. &lt;/span&gt;&lt;span&gt;edges&lt;/span&gt;&lt;span&gt; 테이블과 다시 조인하여 &lt;/span&gt;&lt;span&gt;(A, C)&lt;/span&gt;&lt;span&gt; 또는 &lt;/span&gt;&lt;span&gt;(C, A)&lt;/span&gt;&lt;span&gt; 관계가 있는 경우만 필터링합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 하면 &lt;/span&gt;&lt;span&gt;(A, C)&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;h4 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Step 3: 최종 결과 필터링&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;같은 삼각형이 여러 번 나오는 것을 방지하기 위해 &lt;/span&gt;&lt;span&gt;user_a_id &amp;lt; user_b_id &amp;lt; user_c_id&lt;/span&gt;&lt;span&gt; 조건을 추가합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;특정 사용자가 포함된 삼각형만 출력합니다 (예: &lt;/span&gt;&lt;span&gt;3820&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 &lt;/span&gt;&lt;span&gt;3820&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 쿼리&lt;/h3&gt;
&lt;pre id=&quot;code_1742474682578&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH ab AS (
    SELECT E1.user_a_id, E1.user_b_id, E2.user_b_id AS user_c_id
    FROM edges AS E1
    JOIN edges AS E2 
        ON E1.user_b_id = E2.user_a_id
),
ac AS (
    SELECT ab.user_a_id, ab.user_b_id, ab.user_c_id
    FROM ab
    JOIN edges AS E3
        ON ((ab.user_a_id = E3.user_a_id AND ab.user_c_id = E3.user_b_id) 
         OR (ab.user_a_id = E3.user_b_id AND ab.user_c_id = E3.user_a_id))
)

SELECT * 
FROM ac
WHERE user_a_id &amp;lt; user_b_id 
AND user_b_id &amp;lt; user_c_id
AND 3820 IN (user_a_id, user_b_id, user_c_id)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 핵심 문법 설명&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;  1. SELF JOIN 활용&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;같은 테이블을 두 번 이상 조인하여 관계를 확장할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;본 문제에서는 &lt;/span&gt;&lt;span&gt;edges&lt;/span&gt;&lt;span&gt; 테이블을 &lt;/span&gt;&lt;span&gt;&lt;b&gt;두 번 조인&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하여 &lt;/span&gt;&lt;span&gt;A-B-C&lt;/span&gt;&lt;span&gt; 관계를 찾고, 한 번 더 조인하여 &lt;/span&gt;&lt;span&gt;A-C&lt;/span&gt;&lt;span&gt; 관계를 확인했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;  2. OR 조건을 활용한 대칭 관계 확인&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;친구 관계는 (A, B) 또는 (B, A)로 저장될 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;(A, C) 관계 확인&lt;/span&gt;&lt;span&gt; 단계에서 &lt;/span&gt;&lt;span&gt;OR&lt;/span&gt;&lt;span&gt; 조건을 추가하여 &lt;/span&gt;&lt;span&gt;&lt;b&gt;대칭적 친구 관계&lt;/b&gt;&lt;/span&gt;&lt;span&gt;를 고려했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;  마무리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 SQL 쿼리는 소셜 네트워크에서 삼각관계(클러스터링 구조)를 찾는 문제를 해결했습니다. &lt;/span&gt;&lt;span&gt;WITH AS&lt;/span&gt;&lt;span&gt;를 활용한 구조화된 접근 방식을 사용하여:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;(A &amp;rarr; B &amp;rarr; C) 관계를 구성&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하고,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;(A, C) 관계를 확인하여 삼각형 필터링&lt;/b&gt;&lt;/span&gt;&lt;span&gt;한 후,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;3820이 포함된 삼각형만 출력&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하는 방식으로 문제를 해결했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 방법을 활용하면, &lt;/span&gt;&lt;span&gt;&lt;b&gt;친구 네트워크의 밀도를 분석&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하거나 &lt;/span&gt;&lt;span&gt;&lt;b&gt;추천 시스템을 설계&lt;/b&gt;&lt;/span&gt;&lt;span&gt;하는 데에도 활용할 수 있습니다!&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>SQL</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/15</guid>
      <comments>https://jy9892.tistory.com/15#entry15comment</comments>
      <pubDate>Thu, 20 Mar 2025 21:47:43 +0900</pubDate>
    </item>
    <item>
      <title>[python/프로그래머스 LV1] 과일 장수</title>
      <link>https://jy9892.tistory.com/14</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/135808&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/135808&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1740322823944&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/135808&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/crOTmk/hyYjGBxjgM/Kx9lta6ceYs4BLlK0tBuO1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/KQ7ti/hyYjqyNf8M/sd8Rk2hB775qD2jXhXoGp0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/135808&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/135808&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/crOTmk/hyYjGBxjgM/Kx9lta6ceYs4BLlK0tBuO1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/KQ7ti/hyYjqyNf8M/sd8Rk2hB775qD2jXhXoGp0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;236&quot; data-start=&quot;221&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  문제 이해&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;258&quot; data-start=&quot;238&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1️⃣ 사과 포장 규칙&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;413&quot; data-start=&quot;259&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;286&quot; data-start=&quot;259&quot;&gt;한 상자에는 &lt;b&gt;m개씩&lt;/b&gt; 담아야 합니다.&lt;/li&gt;
&lt;li data-end=&quot;339&quot; data-start=&quot;287&quot;&gt;&lt;b&gt;상자에 담긴 사과 중 최소 점수가 p일 때, 상자의 가격은 p &amp;times; m입니다.&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;375&quot; data-start=&quot;340&quot;&gt;&lt;b&gt;최대 이익을 얻을 수 있도록 사과를 포장해야 합니다.&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;413&quot; data-start=&quot;376&quot;&gt;사과가 남더라도 &lt;b&gt;m개를 채우지 못하면 버려야 합니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&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;h2 data-end=&quot;1088&quot; data-start=&quot;1062&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  최적의 이익을 구하는 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1247&quot; data-start=&quot;1089&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1147&quot; data-start=&quot;1089&quot;&gt;&lt;b&gt;사과 점수를 내림차순 정렬&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1147&quot; data-start=&quot;1114&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1147&quot; data-start=&quot;1114&quot;&gt;큰 점수부터 함께 묶어야 &lt;b&gt;그룹의 최소값이 높아짐&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1201&quot; data-start=&quot;1148&quot;&gt;&lt;b&gt;m개씩 묶어 최대한 많은 상자를 만듦&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1201&quot; data-start=&quot;1181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1201&quot; data-start=&quot;1181&quot;&gt;m개가 안 되는 사과는 버림.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1247&quot; data-start=&quot;1202&quot;&gt;&lt;b&gt;각 그룹의 최소값을 찾아 p &amp;times; m을 계산하여 최대 이익을 구함.&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1740323053448&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(k, m, score):
    answer = 0  # 총 이익
    
    score.sort(reverse=True)  # 내림차순 정렬
    
    i = 0  # 시작 인덱스
    while (i + m &amp;lt;= len(score)):  # `m`개 이상 남아있을 때만 반복
        box = score[i : i + m]  # `m`개씩 슬라이싱하여 상자 만들기
        price = min(box) * m  # 최소값 &amp;times; `m`
        answer += price  # 총 이익 누적
        i += m  # 다음 그룹으로 이동
        
    return answer  # 최대 이익 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1696&quot; data-start=&quot;1681&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;1696&quot; data-start=&quot;1681&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  코드 설명&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;1713&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  핵심 로직&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2053&quot; data-start=&quot;1714&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2053&quot; data-start=&quot;1742&quot;&gt;
&lt;tr data-end=&quot;1801&quot; data-start=&quot;1742&quot;&gt;
&lt;td&gt;score.sort(reverse=True)&lt;/td&gt;
&lt;td&gt;사과 점수를 내림차순 정렬하여 최상품부터 그룹화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1877&quot; data-start=&quot;1802&quot;&gt;
&lt;td&gt;while (i + m &amp;lt;= len(score)):&lt;/td&gt;
&lt;td&gt;m개 이상 남아 있을 때만 그룹을 만듦 (리스트 범위 초과 방지)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1932&quot; data-start=&quot;1878&quot;&gt;
&lt;td&gt;box = score[i : i + m]&lt;/td&gt;
&lt;td&gt;리스트 슬라이싱을 사용해 m개씩 그룹화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1987&quot; data-start=&quot;1933&quot;&gt;
&lt;td&gt;price = min(box) * m&lt;/td&gt;
&lt;td&gt;그룹 내 최소 점수 &amp;times; m (상자의 가격)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2019&quot; data-start=&quot;1988&quot;&gt;
&lt;td&gt;answer += price&lt;/td&gt;
&lt;td&gt;총 이익 누적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2053&quot; data-start=&quot;2020&quot;&gt;
&lt;td&gt;i += m&lt;/td&gt;
&lt;td&gt;다음 m개를 위해 인덱스 이동&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;h2 data-end=&quot;2078&quot; data-start=&quot;2060&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-end=&quot;2078&quot; data-start=&quot;2060&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  실행 흐름 예제&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;2095&quot; data-start=&quot;2079&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  예제 실행&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1740323160344&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(solution(3, 4, [1, 2, 3, 1, 2, 3, 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;정렬&amp;nbsp;&amp;rarr;&amp;nbsp;[3,&amp;nbsp;3,&amp;nbsp;2,&amp;nbsp;2,&amp;nbsp;1,&amp;nbsp;1,&amp;nbsp;1] &lt;br /&gt;첫&amp;nbsp;번째&amp;nbsp;그룹:&amp;nbsp;[3,&amp;nbsp;3,&amp;nbsp;2,&amp;nbsp;2]&amp;nbsp;&amp;rarr;&amp;nbsp;최소값&amp;nbsp;2&amp;nbsp;&amp;times;&amp;nbsp;4&amp;nbsp;=&amp;nbsp;8 &lt;br /&gt;남은&amp;nbsp;[1,&amp;nbsp;1,&amp;nbsp;1]은&amp;nbsp;버림. &lt;br /&gt;최종&amp;nbsp;이익&amp;nbsp;=&amp;nbsp;8&lt;/p&gt;</description>
      <category>PYTHON</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/14</guid>
      <comments>https://jy9892.tistory.com/14#entry14comment</comments>
      <pubDate>Mon, 24 Feb 2025 00:06:35 +0900</pubDate>
    </item>
    <item>
      <title>[SQL/프로그래머스 LV3] 멀티 플랫폼 게임 찾기</title>
      <link>https://jy9892.tistory.com/13</link>
      <description>&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://solvesql.com/problems/multiplatform-games/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://solvesql.com/problems/multiplatform-games/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1738755406209&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://solvesql.com/problems/multiplatform-games/&quot; data-og-description=&quot;&quot; data-og-host=&quot;solvesql.com&quot; data-og-source-url=&quot;https://solvesql.com/problems/multiplatform-games/&quot; data-og-url=&quot;https://solvesql.com/problems/multiplatform-games/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://solvesql.com/problems/multiplatform-games/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://solvesql.com/problems/multiplatform-games/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://solvesql.com/problems/multiplatform-games/&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;solvesql.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  문제 상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게임 데이터에서 &lt;b&gt;2012년 이후 출시된 게임 중, 두 개 이상의 서로 다른 제조사(Sony, Nintendo, Microsoft)에서 출시된 게임을 찾는 문제&lt;/b&gt;입니다. 즉, &lt;b&gt;멀티 플랫폼 게임을 확인하고, 특정 게임이 다양한 제조사의 기기에서 출시되었는지 분석&lt;/b&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 문제 접근&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;제조사 매핑 (CASE 문 활용)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;platforms 테이블의 name을 활용해 &lt;b&gt;플랫폼별 제조사(Sony, Nintendo, Microsoft)를 분류&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li&gt;이 결과를 WITH plat AS (...))으로 저장하여, 제조사 정보를 포함한 데이터셋을 만듭니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;게임 데이터와 제조사 정보 결합&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;games 테이블과 platforms 테이블을 &lt;b&gt;platform_id를 기준으로 조인&lt;/b&gt;하여, 각 게임이 출시된 제조사를 연결합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2012년 이후 출시된 게임만 선택&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;두 개 이상의 제조사에서 출시된 게임 찾기&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;같은 게임(g.name)이 &lt;b&gt;다른 제조사에서 출시된 경우&lt;/b&gt;를 찾기 위해 GROUP BY g.name을 적용합니다.&lt;/li&gt;
&lt;li&gt;HAVING COUNT(DISTINCT p.company) &amp;gt;= 2 조건을 사용하여 &lt;b&gt;2개 이상의 제조사에서 출시된 게임만 필터링&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 쿼리&lt;/h3&gt;
&lt;pre id=&quot;code_1738755510745&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH plat AS (
  SELECT name, 
         platform_id, 
         CASE 
             WHEN name IN ('PS3', 'PS4', 'PSP', 'PSV') THEN 'Sony'
             WHEN name IN ('Wii', 'WiiU', 'DS', '3DS') THEN 'Nintendo'
             WHEN name IN ('X360', 'XONE') THEN 'Microsoft'
         END AS company
  FROM platforms
)

SELECT DISTINCT g.name
FROM games AS g
JOIN plat AS p
ON g.platform_id = p.platform_id
WHERE g.year &amp;gt;= 2012
GROUP BY g.name
HAVING COUNT(DISTINCT p.company) &amp;gt;= 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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 핵심 문법 설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  1. WITH AS 절 (공통 테이블 표현식, CTE)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WITH AS 절은 &lt;b&gt;서브쿼리(임시 테이블)를 생성하여, 이후 메인 쿼리에서 재사용하는 방식&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;한 번 정의된 WITH 절은 쿼리 내에서 여러 번 사용할 수 있어 &lt;b&gt;코드 중복을 줄입니다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738755686593&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH 테이블명 AS (
    SELECT 컬럼명
    FROM 원본테이블
    WHERE 조건
)
SELECT * FROM 테이블명;&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: #333333; text-align: start;&quot;&gt; &lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;. CASE WHEN 절&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CASE WHEN은 SQL에서 &lt;b&gt;IF-ELSE 문과 비슷한 역할&lt;/b&gt;을 합니다.&lt;/li&gt;
&lt;li&gt;특정 조건을 만족하면 해당 값을 반환하며, 조건을 만족하지 않는 경우 ELSE를 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738755740985&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CASE 
    WHEN 조건1 THEN 결과1
    WHEN 조건2 THEN 결과2
    ELSE 결과3
END AS 컬럼명&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt; 마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 쿼리는 &lt;b&gt;2012년 이후 출시된 게임 중, 두 개 이상의 서로 다른 제조사(Sony, Nintendo, Microsoft)에서 출시된 게임을 찾는 문제를 해결하기 위해 WITH AS와 CASE WHEN을 활용했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 플랫폼 데이터를 제조사별로 그룹화하고, JOIN 및 HAVING COUNT(DISTINCT) 조건을 사용하여 다중 제조사에서 출시된 게임을 효과적으로 필터링할 수 있었습니다.&lt;/p&gt;</description>
      <category>SQL</category>
      <category>CASE WHEN</category>
      <category>distinct</category>
      <category>having count</category>
      <category>join</category>
      <category>solvesql</category>
      <category>SQL</category>
      <category>with as</category>
      <category>멀티 플랫폼 게임 찾기</category>
      <category>코딩테스트</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/13</guid>
      <comments>https://jy9892.tistory.com/13#entry13comment</comments>
      <pubDate>Wed, 5 Feb 2025 20:45:24 +0900</pubDate>
    </item>
    <item>
      <title>[python/프로그래머스 LV1] K번째수</title>
      <link>https://jy9892.tistory.com/12</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42748&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42748&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1738745472484&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42748&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cdIIVL/hyYcfX4NLi/sMPh3n6pLEIwb3NtOy3Jvk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42748&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42748&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cdIIVL/hyYcfX4NLi/sMPh3n6pLEIwb3NtOy3Jvk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 리스트 array에서 특정 구간을 &lt;b&gt;자르고 &amp;rarr; 정렬하고 &amp;rarr; k번째 값을 찾는 문제&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;배열에서 i번째부터 j번째까지 자르기&lt;/li&gt;
&lt;li&gt;정렬하기&lt;/li&gt;
&lt;li&gt;k번째 값 찾기&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, array = [1, 5, 2, 6, 3, 7, 4]이고 commands = [[2, 5, 3], [4, 4, 1], [1, 7, 3]]라면:&lt;br /&gt;첫 번째 명령어 [2, 5, 3]을 처리하는 과정을 보면,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;array의 2번째부터 5번째까지 가져오면 [5, 2, 6, 3]&lt;/li&gt;
&lt;li&gt;이를 정렬하면 [2, 3, 5, 6]&lt;/li&gt;
&lt;li&gt;여기서 3번째 값은 5&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 방식으로 각 commands를 처리한 결과를 리스트로 반환하는 문제입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1738745508071&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(array, commands):
    answer = []
    
    for command in commands:
        i, j, k = command
        sliced_array = sorted(array[i-1:j])  # 리스트 자르고 정렬
        answer.append(sliced_array[k-1])  # k번째 값 추가
    
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드해석&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1738745692782&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(array, commands):
   answer = []
       for command in commands:
        i, j, k = command&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;1. solution 함수는 두 개의 인자를 받습니다: array(숫자리스트), commands(여러개의 i,j,k를 담는 리스트)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- commands의 각 원소는 [i, j, k] 형태이며, &lt;b&gt;슬라이싱 범위(i~j)와 k번째 값을 의미&lt;/b&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;2. 최종 결과를 저장할 빈 리스트 answer를 생성합니다.&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. commands 리스트를 하나씩 순회하며 [i, j, k]를 가져옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- command는 [i, j, k] 형태의 리스트이며, 이를 &lt;b&gt;변수 i, j, k에 할당&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1738745783151&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1회차: i=2, j=5, k=3  (command = [2, 5, 3])
2회차: i=4, j=4, k=1  (command = [4, 4, 1])
3회차: i=1, j=7, k=3  (command = [1, 7, 3])&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_1738745843862&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sliced = sorted(array[i-1:j])
answer.append(sliced[k-1])
return answer&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;4. array[i-1:j] : &lt;b&gt;리스트 슬라이싱&lt;/b&gt;을 사용하여 i번째부터 j번째까지의 요소를 추출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Python의 인덱스는 &lt;b&gt;0부터 시작&lt;/b&gt;하므로, i-1을 사용합니다.&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;5. sorted(...) : 슬라이싱한 리스트를 정렬합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예제에서 [5, 2, 6, 3] &amp;rarr; [2, 3, 5, 6]&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;6. 정렬된 리스트에서 k번째 값을 찾고, 이 값을 answer 리스트에 추가합니다.&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;7. 모든 commands를 처리한 후 최종 결과 answer를 반환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드 요약&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✔ commands 리스트를 하나씩 반복하며 [i, j, k] 값을 가져옴&lt;br /&gt;✔ array에서 i~j 범위를 슬라이싱&lt;br /&gt;✔ 정렬 후 k번째 값을 answer 리스트에 추가&lt;br /&gt;✔ answer를 반환&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;b&gt;  사용된 주요 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;✅ 리스트 슬라이싱 (array[i-1:j])&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리스트의 일부를 가져올 때 사용됩니다.&lt;/li&gt;
&lt;li&gt;i번째 ~ j번째를 가져오려면 &lt;b&gt;Python은 0부터 시작하는 인덱스 시스템&lt;/b&gt;이므로, i-1을 사용해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738745539686&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;arr = [10, 20, 30, 40, 50]
print(arr[1:4])  # [20, 30, 40]  (index 1 ~ 3까지 포함)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;✅ sorted() 함수&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리스트를 정렬할 때 사용됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;새로운 정렬된 리스트를 반환&lt;/b&gt;하며, 원본 리스트는 변경되지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738745564807&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;arr = [3, 1, 4, 1, 5]
sorted_arr = sorted(arr)  # [1, 1, 3, 4, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;✅ list.append(value)&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리스트에 새로운 값을 추가할 때 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738745579439&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;numbers = [1, 2, 3]
numbers.append(4)
print(numbers)  # [1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;✅ 리스트 인덱싱 (list[index])&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리스트의 특정 위치 값을 가져오는 방법입니다.&lt;/li&gt;
&lt;li&gt;Python의 인덱스는 &lt;b&gt;0부터 시작&lt;/b&gt;하므로 k번째 요소는 k-1 인덱스로 접근합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1738745598359&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;arr = [10, 20, 30, 40, 50]
print(arr[2])  # 3번째 요소 (30)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;</description>
      <category>PYTHON</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/12</guid>
      <comments>https://jy9892.tistory.com/12#entry12comment</comments>
      <pubDate>Wed, 5 Feb 2025 18:01:26 +0900</pubDate>
    </item>
    <item>
      <title>[SQL/프로그래머스 LV3] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기</title>
      <link>https://jy9892.tistory.com/11</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/151139&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/151139&lt;/a&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;figure id=&quot;og_1737028482163&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/151139&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ewKFp/hyX0AinKRX/20LbK8dKbZ5Kz7KGNt7DOk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/bFK6Hy/hyX0vH9dIq/JgXs2ZkPHDRVqXRytPfaG1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/151139&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/151139&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ewKFp/hyX0AinKRX/20LbK8dKbZ5Kz7KGNt7DOk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/bFK6Hy/hyX0vH9dIq/JgXs2ZkPHDRVqXRytPfaG1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문제 상황:&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;월별로 &lt;b&gt;대여 횟수가 5회 이상인 차량&lt;/b&gt;만 필터링하고, 이러한 차량의 월별 대여 횟수를 계산.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문제 접근:&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단계 1: 총 대여 횟수가 5회 이상인 차량 필터링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, CAR_ID를 기준으로 그룹화하여 차량별 총 대여 횟수를 계산합니다. 이 중 대여 횟수가 5회 이상인 차량만 추출합니다&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;단계 2: 조건을 만족하는 차량과 원본 데이터를 결합&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 대여 횟수가 5회 이상인 차량만 남긴 서브쿼리 결과를 원본 테이블과 JOIN합니다. 이를 통해 조건에 맞는 차량의 모든 대여 기록을 가져옵니다.&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;단계 3: 월별 대여 횟수를 계산&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건을 만족하는 차량의 대여 기록에서 월별 대여 횟수를 계산합니다. 이를 위해:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;MONTH(P.START_DATE)로 월을 추출.&lt;/li&gt;
&lt;li&gt;GROUP BY를 사용해 월(MONTH)과 차량 ID(CAR_ID)별로 그룹화.&lt;/li&gt;
&lt;li&gt;COUNT(P.HISTORY_ID)를 사용해 월별 대여 횟수를 집계.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;논리 흐름:&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;필터링 조건 정의:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전체 데이터&lt;/b&gt;에서 총 대여 횟수가 5회 이상인 차량만 남깁니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;조건 만족 차량과 원본 데이터 결합:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CAR_ID를 기준으로 서브쿼리와 원본 데이터를 JOIN하여, 필터링된 차량의 모든 대여 기록을 가져옵니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;월별 집계:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대여 시작 날짜(START_DATE)에서 월(MONTH)을 추출하여 GROUP BY로 그룹화.&lt;/li&gt;
&lt;li&gt;각 월별로 대여 횟수를 계산합니다.&lt;/li&gt;
&lt;/ul&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;쿼리:&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1737028507061&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    MONTH(P.START_DATE) AS MONTH, 
    P.CAR_ID, 
    COUNT(P.HISTORY_ID) AS MONTHLY_RECORDS
FROM 
    CAR_RENTAL_COMPANY_RENTAL_HISTORY AS P
JOIN (
    SELECT 
        CAR_ID
    FROM 
        CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE 
        START_DATE &amp;gt;= '2022-08-01' AND START_DATE &amp;lt;= '2022-10-31'
    GROUP BY 
        CAR_ID
    HAVING 
        COUNT(HISTORY_ID) &amp;gt;= 5
) AS A
ON 
    P.CAR_ID = A.CAR_ID
WHERE 
    P.START_DATE &amp;gt;= '2022-08-01' AND P.START_DATE &amp;lt;= '2022-10-31'
GROUP BY 
    MONTH(P.START_DATE), P.CAR_ID
ORDER BY 
    MONTH ASC, P.CAR_ID 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;&lt;b&gt;서브쿼리 (A)&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CAR_ID별로 전체 대여 횟수를 계산하고, 5회 이상 대여된 차량만 필터링합니다:&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JOIN&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서브쿼리 결과(A)와 원본 테이블(P)을 CAR_ID 기준으로 JOIN하여, 조건을 만족하는 차량의 월별 데이터를 필터링합니다:&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;월별 대여 횟수 계산&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;COUNT(P.HISTORY_ID)를 사용하여 P.START_DATE에서 추출한 월별 대여 횟수를 계산합니다.&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GROUP BY&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MONTH(P.START_DATE)와 P.CAR_ID를 기준으로 그룹화하여 월별로 집계합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;최종 출력&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MONTHLY_RECORDS 열에 각 월별 차량의 대여 횟수를 출력합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;얻은 인사이트:&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;그룹화와 서브쿼리의 활용:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GROUP BY와 &lt;b&gt;서브쿼리&lt;/b&gt;를 활용하여 특정 조건을 만족하는 데이터를 효율적으로 필터링할 수 있었습니다.&lt;/li&gt;
&lt;li&gt;서브쿼리 내에서 CAR_ID별로 대여 횟수를 집계하고, 이를 JOIN하여 원본 데이터를 필터링함으로써 정확한 결과를 도출할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JOIN을 통한 데이터 결합:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;JOIN&lt;/b&gt;을 활용하여 서브쿼리의 결과와 원본 데이터를 결합함으로써, 조건을 만족하는 데이터만을 추출할 수 있었습니다.&lt;/li&gt;
&lt;li&gt;이는 대규모 데이터셋에서 특정 조건을 만족하는 데이터를 효율적으로 처리하는 데 유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SQL 문법의 중요성:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;비교 연산자&lt;/b&gt;의 올바른 사용 (&amp;lt;= vs =&amp;lt;)과 &lt;b&gt;서브쿼리의 별칭&lt;/b&gt; 지정은 SQL 쿼리 작성 시 필수적인 요소입니다.&lt;/li&gt;
&lt;li&gt;잘못된 문법은 예상치 못한 오류를 발생시킬 수 있으므로, 항상 주의가 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 집계의 정확성:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;COUNT(history_id) &amp;gt;= 5&lt;/b&gt; 조건을 통해, 총 대여 횟수가 5회 이상인 차량만을 대상으로 분석함으로써, 보다 의미 있는 데이터를 얻을 수 있었습니다.&lt;/li&gt;
&lt;li&gt;이는 분석 목적에 맞는 정확한 데이터 집계의 중요성을 보여줍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>SQL</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/11</guid>
      <comments>https://jy9892.tistory.com/11#entry11comment</comments>
      <pubDate>Fri, 17 Jan 2025 10:00:13 +0900</pubDate>
    </item>
    <item>
      <title>[SQL/프로그래머스 LV.3] 헤비 유저가 소유한 장소</title>
      <link>https://jy9892.tistory.com/10</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/77487&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/77487&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737010315571&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/77487&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8gS0M/hyX4qLTa6C/6LJUZmAvJqZir0xVKrqPVk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/byZ0mT/hyX4t9Gmwp/A9AnXSo9sva441RDI5Wwk1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/77487&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/77487&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8gS0M/hyX4qLTa6C/6LJUZmAvJqZir0xVKrqPVk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/byZ0mT/hyX4t9Gmwp/A9AnXSo9sva441RDI5Wwk1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SQL에서 그룹화와 서브쿼리를 활용한 데이터 필터링: 사례 분석&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 문제 상황: 데이터 필터링 오류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL에서 GROUP BY와 HAVING을 활용해 특정 조건에 맞는 데이터를 추출하려고 했으나, 작성한 쿼리가 제대로 작동하지 않았습니다. 아래는 처음 작성한 쿼리입니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737010406357&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM (
    SELECT *
    FROM PLACES
    GROUP BY HOST_ID
    HAVING COUNT(HOST_ID) &amp;gt;= 2
)



SELECT ID, NAME, HOST_ID
FROM (
    SELECT HOST_ID, COUNT(HOST_ID) AS HOST_COUNT, NAME, ID
    FROM PLACES
    GROUP BY HOST_ID
    HAVING COUNT(HOST_ID) &amp;gt;= 2
) AS HEAVY&lt;/code&gt;&lt;/pre&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;b&gt;2. 오류 원인&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;GROUP BY와 SELECT *의 문제&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GROUP BY는 그룹화 기준(HOST_ID) 및 집계 함수(COUNT(HOST_ID))로 데이터를 반환합니다.&lt;/li&gt;
&lt;li&gt;하지만 SELECT * 또는 SELECT ID, NAME, HOST_ID와 같이 다른 열을 함께 선택하려면, 그룹화되지 않은 열을 반환할 수 없으므로 SQL 문법상 오류가 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;의도와 실행의 불일치&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 쿼리는 HOST_ID를 기준으로 그룹화된 데이터에서 ID, NAME, HOST_ID를 모두 가져오고자 했지만, 그룹화되지 않은 열(ID, NAME)은 쿼리에 포함할 수 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;올바른 결과를 위한 JOIN 필요성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그룹화 결과에 해당하는 데이터를 원본 테이블에서 가져오려면, JOIN을 활용해 데이터를 연결해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서브쿼리 별칭 :&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQL에서 서브쿼리(derived table)를 사용할 때는 각 서브쿼리에 반드시 별칭(alias)을 지정해야 합니다.&lt;/li&gt;
&lt;li&gt;MySQL에서는 서브쿼리에 별칭이 없으면 Every derived table must have its own alias 오류가 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 수정한 쿼리&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1737010517908&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT P.ID, P.NAME, P.HOST_ID
FROM PLACES AS P
JOIN (
    SELECT HOST_ID
    FROM PLACES
    GROUP BY HOST_ID
    HAVING COUNT(HOST_ID) &amp;gt;= 2
) AS HEAVY
ON P.HOST_ID = HEAVY.HOST_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;b&gt;서브쿼리 (HEAVY)&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GROUP BY와 HAVING을 사용해 HOST_ID가 2번 이상 등장하는 경우만 추출합니다.&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;b&gt;JOIN 활용&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원본 테이블(PLACES)과 서브쿼리 결과(HEAVY)를 HOST_ID를 기준으로 JOIN.&lt;/li&gt;
&lt;li&gt;조건에 맞는 HOST_ID를 가진 데이터의 모든 열(ID, NAME, HOST_ID)을 원본 테이블에서 가져옵니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;최종 결과&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HOST_ID가 2번 이상 등장하는 행만 필터링된 결과를 반환.&lt;/li&gt;
&lt;/ul&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;b&gt;4. 얻은 인사이트&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1️⃣ GROUP BY와 SELECT 사용의 원칙&lt;/b&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;b&gt;GROUP BY&lt;/b&gt;를 사용할 때는 그룹화 기준 열과 집계 함수로만 데이터를 반환할 수 있습니다.&lt;/li&gt;
&lt;li&gt;그룹화되지 않은 다른 열을 가져오려면, 집계 함수(예: MAX, MIN, ANY_VALUE) 또는 JOIN을 활용해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2️⃣ JOIN 활용&lt;/b&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;b&gt;서브쿼리와 JOIN&lt;/b&gt;을 활용해야 합니다.&lt;/li&gt;
&lt;li&gt;이 방법은 조건에 맞는 데이터 필터링 후 원본 테이블의 모든 열을 반환할 때 유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3️⃣ SQL 작성 시 단계별 설계 중요성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원하는 결과를 얻기 위해 SQL 쿼리를 단계적으로 설계하고, 중간 결과를 확인하는 과정이 중요합니다.&lt;/li&gt;
&lt;li&gt;조건 설정(HAVING)과 데이터 연결(JOIN)의 역할을 명확히 이해하면 문제 해결이 수월해집니다.&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;b&gt;그룹화된 데이터를 원본 테이블과 매칭하여 필요한 모든 데이터를 가져오는 방법&lt;/b&gt;을 이해할 수 있었습니다. 중요한 점은 SQL의 GROUP BY, HAVING, 그리고 JOIN의 역할을 명확히 이해하고, 각각의 기능을 적절히 활용하는 것입니다. SQL로 복잡한 데이터를 다룰 때도 &lt;b&gt;&quot;문제의 원인 분석 &amp;rarr; 설계 &amp;rarr; 구현&quot;&lt;/b&gt; 과정을 거치면 효과적으로 문제를 해결할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SQL</category>
      <category>SQL 오류</category>
      <category>문법 오류</category>
      <category>서브쿼리</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <category>헤비 유저가 소유한 장소</category>
      <author>jy9892</author>
      <guid isPermaLink="true">https://jy9892.tistory.com/10</guid>
      <comments>https://jy9892.tistory.com/10#entry10comment</comments>
      <pubDate>Thu, 16 Jan 2025 16:00:44 +0900</pubDate>
    </item>
  </channel>
</rss>