<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>DATALOG</title>
    <link>https://duswjd00.tistory.com/</link>
    <description>데이터 분석가</description>
    <language>ko</language>
    <pubDate>Wed, 29 Jul 2026 09:26:39 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>duswjd_data</managingEditor>
    <item>
      <title>1075. Project Employees I</title>
      <link>https://duswjd00.tistory.com/157</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdoR0m/dJMb9VNhivA/pvurpPmCpTP5XponZgOuZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdoR0m/dJMb9VNhivA/pvurpPmCpTP5XponZgOuZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdoR0m/dJMb9VNhivA/pvurpPmCpTP5XponZgOuZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdoR0m%2FdJMb9VNhivA%2FpvurpPmCpTP5XponZgOuZ0%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;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/project-employees-i/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/project-employees-i/description/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;span&gt;&amp;nbsp;&lt;/span&gt;설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 project_id별로 그 프로젝트에 참여한 직원들의 평균 경력(experience_years)을 계산해서,&lt;br /&gt;소수점 둘째 자리까지 반올림(ROUND) 한 값을 구하기&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760616851501&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT p.project_id,
       ROUND(SUM(e.experience_years)/COUNT(p.project_id),2) AS average_years
FROM project p LEFT JOIN employee e ON p.employee_id = e.employee_id
GROUP BY p.project_id&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&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;SUM()/COUNT()로도 가능하지만 &amp;rarr; AVG(e.experience_years)로 계산 가능&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이 문제에서는 모든 프로젝트에 직원이 존재하므로 &lt;/span&gt;LEFT JOIN 대신 JOIN(= INNER JOIN)이 &lt;b&gt;논리적으로 더 적합&lt;br /&gt;&lt;/b&gt; &amp;rarr;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 필요한 데이터만 정확히 매칭 가능 (불필요하게 NULL 값 포함할 가능성 없음)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;개선 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760617224684&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT p.project_id,
       ROUND(AVG(e.experience_years),2) AS average_years
FROM project p JOIN employee e ON p.employee_id = e.employee_id
GROUP BY p.project_id&lt;/code&gt;&lt;/pre&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/157</guid>
      <comments>https://duswjd00.tistory.com/157#entry157comment</comments>
      <pubDate>Fri, 17 Oct 2025 09:24:59 +0900</pubDate>
    </item>
    <item>
      <title>1251. Average Selling Price</title>
      <link>https://duswjd00.tistory.com/156</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mpoyZ/btsRbCGZG6v/9VEJ9Qby7IgrKKKnMhjQ00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mpoyZ/btsRbCGZG6v/9VEJ9Qby7IgrKKKnMhjQ00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mpoyZ/btsRbCGZG6v/9VEJ9Qby7IgrKKKnMhjQ00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmpoyZ%2FbtsRbCGZG6v%2F9VEJ9Qby7IgrKKKnMhjQ00%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;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/average-selling-price/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/average-selling-price/description/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;span&gt;&amp;nbsp;&lt;/span&gt;설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;297&quot; data-start=&quot;272&quot; data-ke-size=&quot;size16&quot;&gt;요구사항: 각 제품별 평균 판매 단가 계산&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;396&quot; data-start=&quot;300&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;345&quot; data-start=&quot;300&quot;&gt;평균 판매 단가 = (price &amp;times; units) 총합 &amp;divide; 총 판매 수량&lt;/li&gt;
&lt;li data-end=&quot;367&quot; data-start=&quot;348&quot;&gt;소수점 둘째 자리까지 반올림&lt;/li&gt;
&lt;li data-end=&quot;396&quot; data-start=&quot;370&quot;&gt;판매 기록이 없으면 평균 판매가 0으로 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760538076811&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT p.product_id,
       IFNULL(ROUND(SUM(u.units*p.price)/SUM(u.units),2),0) AS average_price
FROM prices p
    LEFT JOIN unitssold u ON p.product_id = u.product_id
    AND u.purchase_date BETWEEN p.start_date AND p.end_date
GROUP BY p.product_id&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;코드 설명&lt;/h3&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 data-end=&quot;548&quot; data-start=&quot;418&quot;&gt;&lt;b&gt;판매 기록이 없을 수도 있음&lt;/b&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;548&quot; data-start=&quot;446&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;548&quot; data-start=&quot;504&quot;&gt;&lt;b&gt;Prices를 기준으로 LEFT JOIN&lt;/b&gt; 해야 모든 제품 포함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;654&quot; data-start=&quot;549&quot;&gt;&lt;b&gt;날짜 조건 조인&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;654&quot; data-start=&quot;570&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;621&quot; data-start=&quot;570&quot;&gt;purchase_date BETWEEN start_date AND end_date&lt;/li&gt;
&lt;li data-end=&quot;654&quot; data-start=&quot;625&quot;&gt;해당 판매 기록이 어느 가격 기간에 속하는지 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;759&quot; data-start=&quot;655&quot;&gt;&lt;b&gt;평균 계산&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;759&quot; data-start=&quot;673&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;716&quot; data-start=&quot;673&quot;&gt;SUM(u.units * p.price) / SUM(u.units)&lt;/li&gt;
&lt;li data-end=&quot;759&quot; data-start=&quot;720&quot;&gt;판매 기록 없으면 NULL &amp;rarr; IFNULL(..., 0)로 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;810&quot; data-start=&quot;760&quot;&gt;&lt;b&gt;반올림 처리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;810&quot; data-start=&quot;779&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;810&quot; data-start=&quot;779&quot;&gt;ROUND(..., 2) &amp;rarr; 소수점 둘째 자리까지&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;첫 번째 시도 (실패)&lt;/h3&gt;
&lt;pre id=&quot;code_1760537002930&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT p.product_id,
       IFNULL(ROUND((u.units*p.price)/SUM(u.units),2),0) AS average_price
FROM prices p
    LEFT JOIN unitssold u ON p.product_id = u.product_id
    AND u.purchase_date BETWEEN p.start_date AND p.end_date
GROUP BY p.product_id&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;틀린 이유&lt;/h3&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(u.units * p.price) / SUM(u.units)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;한 행의 가격 &amp;times; 수량&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;을 전체 합계(SUM(u.units))로 나누는 형태&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;즉, &lt;b&gt;그룹 전체 평균이 아니라 각 행 단위 비율을 먼저 계산&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&amp;rarr; GROUP BY 이후 집계가 잘못되어 &lt;b&gt;평균이 왜곡&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;됨 (실수하지 말자!)&lt;/span&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;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/156</guid>
      <comments>https://duswjd00.tistory.com/156#entry156comment</comments>
      <pubDate>Thu, 16 Oct 2025 09:27:09 +0900</pubDate>
    </item>
    <item>
      <title>[LV.4] 연습문제 &amp;gt; 둘만의 암호</title>
      <link>https://duswjd00.tistory.com/155</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4EISl/btsRbubeWTN/J55iYLkr9LCHsKTTSG7LfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4EISl/btsRbubeWTN/J55iYLkr9LCHsKTTSG7LfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4EISl/btsRbubeWTN/J55iYLkr9LCHsKTTSG7LfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4EISl%2FbtsRbubeWTN%2FJ55iYLkr9LCHsKTTSG7LfK%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;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/155652&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/155652&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1760532409203&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/155652&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sW9Fz/hyZLz2lNNv/2qmZcJtQF03teljEyo65U1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/blDXo1/hyZLmVF7zR/rqUE7kvO2RHdicMymklIBK/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/155652&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/155652&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sW9Fz/hyZLz2lNNv/2qmZcJtQF03teljEyo65U1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/blDXo1/hyZLmVF7zR/rqUE7kvO2RHdicMymklIBK/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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;104&quot; data-start=&quot;92&quot; data-ke-size=&quot;size23&quot;&gt;문제 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;104&quot; data-start=&quot;92&quot;&gt;문자열 암호화 규칙&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;199&quot; data-start=&quot;84&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;123&quot; data-start=&quot;84&quot;&gt;문자열 s의 각 알파벳을 index만큼 뒤로 밀어준다.&lt;/li&gt;
&lt;li data-end=&quot;152&quot; data-start=&quot;124&quot;&gt;z를 넘어가면 다시 a로 순환한다.&lt;/li&gt;
&lt;li data-end=&quot;199&quot; data-start=&quot;153&quot;&gt;단, skip에 포함된 알파벳은 건너뛴다. (즉, 밀 때 세지 않는다)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;s = &quot;aukks&quot;&lt;br /&gt;skip = &quot;wbqd&quot;&lt;br /&gt;index = 5&lt;br /&gt;&amp;rarr; &quot;happy&quot;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;92&quot; data-end=&quot;104&quot;&gt;참고&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;import string
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이썬 내장 모듈 string을 불러오는 코드로, 문자열 처리에 자주 쓰이는 상수들을 제공&lt;/li&gt;
&lt;li data-end=&quot;199&quot; data-start=&quot;110&quot;&gt;'abcdefghijklmnopqrstuvwxyz' &amp;rarr; string.ascii_lowercase&amp;nbsp;&lt;br /&gt;(a부터 z까지 알파벳을 자동으로 불러옴)&lt;/li&gt;
&lt;li data-end=&quot;328&quot; data-start=&quot;200&quot;&gt;이를 이용해 skip에 포함되지 않은 알파벳만 걸러낼 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;104&quot; data-start=&quot;92&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760534469792&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(s, skip, index):
    import string
    
    # 사용할 수 있는 알파벳 (skip 제외)
    alpabets = [c for c in string.ascii_lowercase if c not in skip]

    answer = ''
    for c in s:
        # 현재 문자의 위치
        pos = alpabets.index(c)
         # index만큼 이동 (순환)
        char = alpabets[(pos+index)%len(alpabets)]
        answer += char
    
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;92&quot; data-end=&quot;104&quot;&gt;동작 원리&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;단계&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;예시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;알파벳에서 skip 제외&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;'a'~'z' 중 w,b,q,d 제거&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;문자 a 찾기&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;인덱스 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;index(5)만큼 이동&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;(0 + 5) % len(alpabets) &amp;rarr; 'h'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;모든 문자 반복&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;'aukks' &amp;rarr; 'happy'&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스] Python</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/155</guid>
      <comments>https://duswjd00.tistory.com/155#entry155comment</comments>
      <pubDate>Wed, 15 Oct 2025 22:29:47 +0900</pubDate>
    </item>
    <item>
      <title>620. Not Boring Movies</title>
      <link>https://duswjd00.tistory.com/154</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFLIpz/btsQ7OnnceB/KzQoaZYftauVHj7GsBdxc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFLIpz/btsQ7OnnceB/KzQoaZYftauVHj7GsBdxc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFLIpz/btsQ7OnnceB/KzQoaZYftauVHj7GsBdxc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFLIpz%2FbtsQ7OnnceB%2FKzQoaZYftauVHj7GsBdxc0%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;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/not-boring-movies/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/not-boring-movies/description/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;영화 테이블(Cinema)에서
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;id가 &lt;b&gt;홀수&lt;/b&gt;이고, description이 &lt;b&gt;&quot;boring&quot;이 아닌 영화&lt;/b&gt;만 선택&lt;/li&gt;
&lt;li&gt;rating 기준으로 &lt;b&gt;내림차순 정렬&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760355261772&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM cinema
WHERE id%2 != 0 AND description != 'boring'
ORDER BY rating DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;참고&lt;/h3&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 data-end=&quot;542&quot; data-start=&quot;484&quot;&gt;&lt;b&gt;MySQL 전용&lt;/b&gt;으로는 &amp;rarr; id % 2 != 0 더 &lt;b&gt;간결하고 직관적&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;639&quot; data-start=&quot;543&quot;&gt;&lt;b&gt;SQL 표준&lt;/b&gt;이나 &lt;b&gt;다른 DB 호환성&lt;/b&gt;(Oracle, SQL Server 등)을 고려한다면 &amp;rarr; MOD(id, 2) = 1이 &lt;b&gt;더 안전&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1760355376179&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
FROM cinema
WHERE MOD(id, 2) = 1 AND description != 'boring'
ORDER BY rating 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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/154</guid>
      <comments>https://duswjd00.tistory.com/154#entry154comment</comments>
      <pubDate>Tue, 14 Oct 2025 09:09:40 +0900</pubDate>
    </item>
    <item>
      <title>1934. Confirmation Rate</title>
      <link>https://duswjd00.tistory.com/153</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdbxEq/btsQ67UvWmc/bDS17aBiEc0GKp3k4zoOG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdbxEq/btsQ67UvWmc/bDS17aBiEc0GKp3k4zoOG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdbxEq/btsQ67UvWmc/bDS17aBiEc0GKp3k4zoOG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdbxEq%2FbtsQ67UvWmc%2FbDS17aBiEc0GKp3k4zoOG0%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;1080&quot; height=&quot;1080&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/confirmation-rate/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/confirmation-rate/description/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;139&quot; data-start=&quot;88&quot;&gt;각 사용자의 확인율(confirmation rate) 을 계산하라.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;178&quot; data-start=&quot;141&quot;&gt;Signups : 모든 가입자 (user_id, 가입 시각)&lt;/li&gt;
&lt;li data-end=&quot;266&quot; data-start=&quot;179&quot;&gt;Confirmations : 각 가입자가 보낸 &amp;ldquo;확인 요청&amp;rdquo; 기록
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;266&quot; data-start=&quot;224&quot;&gt;action 값은 'confirmed' 또는 'timeout'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;302&quot; data-start=&quot;267&quot;&gt;&lt;b&gt;확인율 = confirmed 개수 / 전체 요청 개수&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;340&quot; data-start=&quot;303&quot;&gt;확인 요청이 &lt;b&gt;없는 사용자&lt;/b&gt;의 경우 &amp;rarr; 확인율은 0.00&lt;/li&gt;
&lt;li data-end=&quot;366&quot; data-start=&quot;341&quot;&gt;결과는 &lt;b&gt;소수점 둘째 자리까지 반올림&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760313503615&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT s.user_id,
       CASE WHEN c.action IS NULL THEN 0.00
       	ELSE ROUND(SUM(c.action = &quot;confirmed&quot;)/COUNT(*),2)
       	END AS confirmation_rate
FROM signups s LEFT JOIN confirmations c ON s.user_id = c.user_id
GROUP BY s.user_id&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&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 data-end=&quot;658&quot; data-start=&quot;637&quot;&gt;CASE WHEN c.action IS NULL은 잘못된 위치
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;658&quot; data-start=&quot;637&quot;&gt;GROUP BY 이후 집계 함수(SUM, COUNT)를 쓸 때&lt;br /&gt;&amp;rarr; &lt;b&gt;CASE는 그룹 전체에 대해 한 번만 적용되지 않음&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;658&quot; data-start=&quot;637&quot;&gt;그래서 일부 DB에서는 이 코드가 정상 작동하더라도, &lt;b&gt;로직상으로는 &amp;ldquo;한 행만 NULL이면 전체가 0 처리&amp;rdquo;될 수 있음&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&amp;rarr; &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;IFNULL()&lt;/b&gt;&lt;/span&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;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;COUNT(*) 대신 COUNT(c.action) 사용
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;COUNT(*)는 NULL도 포함해 세기 때문에, LEFT JOIN 결과에서 &lt;b&gt;Confirmations가 전혀 없는 사용자&lt;/b&gt;도 1로 계산될 수 있음&lt;/li&gt;
&lt;li&gt;반면, COUNT(c.action)은 NULL은 세지 않으므로 &amp;rarr; &lt;b&gt;요청이 없을 경우 0으로 정확히 계산됨&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;문자열 리터럴은 'confirmed'로 작성
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;MySQL은 &quot; &quot;를 문자열로 인식하지만, 표준 SQL에서는 ' '이 맞음 &amp;rarr; LeetCode나 다른 SQL엔진에서의 이식성을 고려하면 ' '을 쓰는 게 좋음&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;개선된 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1760315106964&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    s.user_id,
    ROUND(
    	IFNULL(SUM(c.action = 'confirmed') / COUNT(c.action), 0),
        2
    ) AS confirmation_rate
FROM Signups s LEFT JOIN Confirmations c ON s.user_id = c.user_id
GROUP BY s.user_id&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;코드 설명&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LEFT JOIN&lt;/td&gt;
&lt;td&gt;모든 가입자 유지 (확인 요청 없는 사용자도 포함)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUM(c.action = 'confirmed')&lt;/td&gt;
&lt;td&gt;MySQL에서는 조건이 참이면 1, 거짓이면 0 &amp;rarr; confirmed 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COUNT(c.action)&lt;/td&gt;
&lt;td&gt;전체 요청 개수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IFNULL(..., 0)&lt;/td&gt;
&lt;td&gt;요청이 전혀 없는 경우 &amp;rarr; 0으로 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROUND(..., 2)&lt;/td&gt;
&lt;td&gt;두 자리 소수로 반올림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GROUP BY s.user_id&lt;/td&gt;
&lt;td&gt;사용자별 계산&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/153</guid>
      <comments>https://duswjd00.tistory.com/153#entry153comment</comments>
      <pubDate>Mon, 13 Oct 2025 09:30:03 +0900</pubDate>
    </item>
    <item>
      <title>-- 9월 프로젝트 집중 기간 --</title>
      <link>https://duswjd00.tistory.com/145</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스] Python</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/145</guid>
      <comments>https://duswjd00.tistory.com/145#entry145comment</comments>
      <pubDate>Sun, 31 Aug 2025 21:24:31 +0900</pubDate>
    </item>
    <item>
      <title>-- 9월 프로젝트 집중 기간 --</title>
      <link>https://duswjd00.tistory.com/144</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/144</guid>
      <comments>https://duswjd00.tistory.com/144#entry144comment</comments>
      <pubDate>Sun, 31 Aug 2025 21:24:11 +0900</pubDate>
    </item>
    <item>
      <title>570. Managers with at Least 5 Direct Reports</title>
      <link>https://duswjd00.tistory.com/138</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목을 입력해주세요_-001 (1).png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NxMJe/btsQbXZCAzq/VMb0IZKI5akZ0KgkBBuXy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NxMJe/btsQbXZCAzq/VMb0IZKI5akZ0KgkBBuXy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NxMJe/btsQbXZCAzq/VMb0IZKI5akZ0KgkBBuXy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNxMJe%2FbtsQbXZCAzq%2FVMb0IZKI5akZ0KgkBBuXy0%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;1080&quot; height=&quot;1080&quot; data-filename=&quot;제목을 입력해주세요_-001 (1).png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/managers-with-at-least-5-direct-reports/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/managers-with-at-least-5-direct-reports/description/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;직속 부하가 5명 이상인 매니저의 이름을 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1756385911305&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT name
FROM employee
WHERE id IN (SELECT managerId
             FROM employee
             GROUP BY managerID
             HAVING count(managerID) &amp;gt;= 5)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;개선된 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1756386253495&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT name
FROM employee
WHERE id IN (
    SELECT managerId
    FROM employee
    WHERE managerId IS NOT NULL
    GROUP BY managerId
    HAVING COUNT(*) &amp;gt;= 5
)&lt;/code&gt;&lt;/pre&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 data-end=&quot;111&quot; data-start=&quot;14&quot;&gt;&lt;b&gt;WHERE managerId IS NOT NULL 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;111&quot; data-start=&quot;57&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;111&quot; data-start=&quot;57&quot;&gt;NULL 값이 있는 경우 불필요하게 그룹화되므로 제외해야 정확한 결과를 얻을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;206&quot; data-start=&quot;113&quot;&gt;&lt;b&gt;COUNT(*) 사용 권장&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;206&quot; data-start=&quot;140&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;206&quot; data-start=&quot;140&quot;&gt;COUNT(managerId) 대신 COUNT(*)를 쓰면 널 값 여부에 관계없이 모든 행을 정확히 셈&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;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/138</guid>
      <comments>https://duswjd00.tistory.com/138#entry138comment</comments>
      <pubDate>Fri, 29 Aug 2025 09:06:18 +0900</pubDate>
    </item>
    <item>
      <title>1280. Students and Examinations</title>
      <link>https://duswjd00.tistory.com/133</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목을 입력해주세요_-001 (1).png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mmmAy/btsQaiWXgdQ/mkYOTAXXbd9SAGf1oBkk81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mmmAy/btsQaiWXgdQ/mkYOTAXXbd9SAGf1oBkk81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mmmAy/btsQaiWXgdQ/mkYOTAXXbd9SAGf1oBkk81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmmmAy%2FbtsQaiWXgdQ%2FmkYOTAXXbd9SAGf1oBkk81%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;1080&quot; height=&quot;1080&quot; data-filename=&quot;제목을 입력해주세요_-001 (1).png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p style=&quot;color: #222222;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/students-and-examinations/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/students-and-examinations/description/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;모든 학생(Students)과 모든 과목(Subjects)의 조합에 대해, 각 학생이 해당 과목 시험을 몇 번 응시했는지 구하는 쿼리 작성&lt;/li&gt;
&lt;li data-end=&quot;301&quot; data-start=&quot;265&quot;&gt;결과
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;301&quot; data-start=&quot;265&quot;&gt;응시 기록이 없는 경우(0)도 포함&lt;/li&gt;
&lt;li data-end=&quot;350&quot; data-start=&quot;302&quot;&gt;student_id, subject_name 순으로 정렬&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1756301903536&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT s.student_id,
       s.student_name,
       su.subject_name,
       COUNT(e.subject_name) AS attended_exams
FROM students s
    CROSS JOIN subjects su
    LEFT JOIN examinations e ON s.student_id = e.student_id
                                AND su.subject_name = e.subject_name
GROUP BY s.student_id, s.student_name, su.subject_name
ORDER BY s.student_id, su.subject_name&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;코드 설명&lt;/h3&gt;
&lt;pre id=&quot;code_1756302587236&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    s.student_id,              -- 학생의 고유 ID
    s.student_name,            -- 학생 이름
    su.subject_name,           -- 과목 이름
    COUNT(e.subject_name) AS attended_exams  -- 해당 학생이 해당 과목 시험을 본 횟수 (없으면 0)
FROM 
    students AS s              -- 학생 테이블
CROSS JOIN 
    subjects AS su             -- 모든 학생 &amp;times; 모든 과목 조합을 만들기 위한 CROSS JOIN
LEFT JOIN 
    examinations AS e 
    ON s.student_id = e.student_id
    AND su.subject_name = e.subject_name  -- 학생 ID와 과목명이 모두 일치하는 시험 기록을 찾음
GROUP BY 
    s.student_id, 
    s.student_name, 
    su.subject_name           -- 각 학생-과목 조합별로 응시 횟수를 집계
ORDER BY 
    s.student_id, 
    su.subject_name           -- 결과를 학생 ID, 과목 이름 순으로 정렬&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스][리트코드] MySQL</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/133</guid>
      <comments>https://duswjd00.tistory.com/133#entry133comment</comments>
      <pubDate>Thu, 28 Aug 2025 08:53:32 +0900</pubDate>
    </item>
    <item>
      <title>[LV.4] 연습문제 &amp;gt; 대충 만든 자판</title>
      <link>https://duswjd00.tistory.com/132</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;python 커버.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mM1JQ/btsP5pV3OQZ/A5NtH8ygSK4axn1KEtKghK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mM1JQ/btsP5pV3OQZ/A5NtH8ygSK4axn1KEtKghK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mM1JQ/btsP5pV3OQZ/A5NtH8ygSK4axn1KEtKghK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmM1JQ%2FbtsP5pV3OQZ%2FA5NtH8ygSK4axn1KEtKghK%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;1080&quot; height=&quot;1080&quot; data-filename=&quot;python 커버.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&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;h3 style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/160586&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/160586&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756046738938&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/160586&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b9uLIu/hyZzxEI2zB/jji9AUWNcqn5cLdJCwBPi0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/q74sl/hyZzHm3ywE/z317VjZxrshWS5P1JYQvu1/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/160586&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/160586&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b9uLIu/hyZzxEI2zB/jji9AUWNcqn5cLdJCwBPi0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/q74sl/hyZzHm3ywE/z317VjZxrshWS5P1JYQvu1/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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;92&quot; data-end=&quot;104&quot;&gt;문제 설명&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;164&quot; data-start=&quot;51&quot;&gt;keymap[i]: (i+1)번 키에 할당된 문자들&lt;br /&gt;예: keymap[0] = &quot;ABACD&quot; &amp;rarr; 1번 키를 누르면 순서대로 A(1번), B(2번), A(3번), C(4번), D(5번)&lt;/li&gt;
&lt;li data-end=&quot;190&quot; data-start=&quot;166&quot;&gt;targets: 만들고 싶은 문자열들&lt;/li&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;192&quot;&gt;&lt;b&gt;목표&lt;/b&gt;: 각 문자열을 만들기 위해 키를 &lt;b&gt;최소 몇 번 눌러야 하는지&lt;/b&gt; 계산&lt;br /&gt;&amp;rarr; 특정 문자를 만들 수 없으면 -1 반환&lt;/li&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;192&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;823&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mnSMx/btsP26wCV72/qgLL9VxMt0BLCrnrkJ2Zd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mnSMx/btsP26wCV72/qgLL9VxMt0BLCrnrkJ2Zd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mnSMx/btsP26wCV72/qgLL9VxMt0BLCrnrkJ2Zd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmnSMx%2FbtsP26wCV72%2FqgLL9VxMt0BLCrnrkJ2Zd1%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;523&quot; height=&quot;823&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;823&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;104&quot; data-start=&quot;92&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 data-end=&quot;150&quot; data-start=&quot;75&quot;&gt;&lt;b&gt;문자별 최소 누름 수 기록&lt;/b&gt;&lt;br /&gt;&amp;rarr; 모든 키(keymap)를 돌며 각 문자에 대해 &lt;b&gt;가장 적은 누름 수&lt;/b&gt;를 저장&lt;/li&gt;
&lt;li data-end=&quot;218&quot; data-start=&quot;152&quot;&gt;&lt;b&gt;target 문자열 분석&lt;/b&gt;&lt;br /&gt;&amp;rarr; 각 target의 문자를 하나씩 보며 최소 누름 수를 &lt;b&gt;합산&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;288&quot; data-start=&quot;220&quot;&gt;&lt;b&gt;못 누르는 문자 처리&lt;/b&gt;&lt;br /&gt;&amp;rarr; 어떤 문자가 keymap에 &lt;b&gt;아예 없다면&lt;/b&gt; &amp;rarr; 해당 문자열은 -1&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;92&quot; data-end=&quot;104&quot;&gt;정답 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1756046893976&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(keymap, targets):
    min_press = {}

    # 각 문자에 대해 최소 누름 횟수를 계산
    for key in keymap:
        for idx, char in enumerate(key):
            press_count = idx + 1
            if char not in min_press or press_count &amp;lt; min_press[char]:
                min_press[char] = press_count

    result = []

    # 각 타겟 단어별로 계산
    for word in targets:
        total = 0
        for char in word:
            if char in min_press:
                total += min_press[char]
            else:
                total = -1  # 해당 문자를 입력할 수 없음
                break
        result.append(total)

    return result&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;104&quot; data-start=&quot;92&quot; data-ke-size=&quot;size23&quot;&gt;코드 설명&lt;/h3&gt;
&lt;pre id=&quot;code_1756220655980&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(keymap, targets):
    min_press = {}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;323&quot; data-start=&quot;219&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;281&quot; data-start=&quot;219&quot;&gt;각 &lt;b&gt;문자(char)&lt;/b&gt; 에 대해 해당 문자를 입력하기 위한 &lt;b&gt;최소 누름 수&lt;/b&gt;를 저장할 딕셔너리&lt;/li&gt;
&lt;li data-end=&quot;323&quot; data-start=&quot;282&quot;&gt;예: {'A': 1, 'B': 2, 'C': 2} 처럼 저장됨&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1756220717396&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    for key in keymap:
        for idx, char in enumerate(key):
            press_count = idx + 1
            if char not in min_press or press_count &amp;lt; min_press[char]: # 그 문자가 아직 저장되지 않았거나, 현재 누름 수가 이전보다 작다면 &amp;rarr; 최소값으로 갱신
                min_press[char] = press_count&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 data-end=&quot;572&quot; data-start=&quot;560&quot;&gt;동작 요약
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;622&quot; data-start=&quot;573&quot;&gt;keymap은 예를 들어 [&quot;ABACD&quot;, &quot;BCEFD&quot;] 같은 리스트&lt;/li&gt;
&lt;li data-end=&quot;622&quot; data-start=&quot;573&quot;&gt;key는 각 키에 할당된 문자열이며, 이중 반복을 통해 각 문자의 위치(=눌러야 하는 횟수)를 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;706&quot; data-start=&quot;688&quot;&gt;예시: &quot;ABACD&quot;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;730&quot; data-start=&quot;707&quot;&gt;A &amp;rarr; 1번 누름 (인덱스 0 + 1)&lt;/li&gt;
&lt;li data-end=&quot;742&quot; data-start=&quot;731&quot;&gt;B &amp;rarr; 2번 누름&lt;/li&gt;
&lt;li data-end=&quot;782&quot; data-start=&quot;743&quot;&gt;A &amp;rarr; 3번 누름 &amp;rarr; &lt;b&gt;이미 1번 누름으로 저장되어 있어 무시&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;794&quot; data-start=&quot;783&quot;&gt;C &amp;rarr; 4번 누름&lt;/li&gt;
&lt;li data-end=&quot;806&quot; data-start=&quot;795&quot;&gt;D &amp;rarr; 5번 누름&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1756220831062&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    result = []&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1033&quot; data-start=&quot;984&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1033&quot; data-start=&quot;984&quot;&gt;결과를 저장할 리스트. 각 target 문자열에 대한 최소 누름 수 합을 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1756220847962&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    for word in targets:
        total = 0
        for char in word:
            if char in min_press:
                total += min_press[char]
            else:
                total = -1
                break
        result.append(total)

    return result&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 data-end=&quot;1307&quot; data-start=&quot;1295&quot;&gt;동작 설명
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1343&quot; data-start=&quot;1309&quot;&gt;targets는 예: [&quot;ABCD&quot;, &quot;AABB&quot;]&lt;/li&gt;
&lt;li data-end=&quot;1373&quot; data-start=&quot;1344&quot;&gt;각 word(입력해야 할 단어)를 하나씩 처리&lt;/li&gt;
&lt;li data-end=&quot;1406&quot; data-start=&quot;1374&quot;&gt;total은 해당 단어를 입력하기 위한 총 누름 수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1418&quot; data-start=&quot;1408&quot;&gt;내부 로직
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1515&quot; data-start=&quot;1419&quot;&gt;각 문자를 하나씩 검사:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1476&quot; data-start=&quot;1437&quot;&gt;min_press에 해당 문자가 있다면 &amp;rarr; 최소 누름 수를 더함&lt;/li&gt;
&lt;li data-end=&quot;1515&quot; data-start=&quot;1479&quot;&gt;없다면 &amp;rarr; &lt;b&gt;입력이 불가능하므로 -1로 설정 후 중단&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1550&quot; data-start=&quot;1516&quot;&gt;처리 후 result 리스트에 총합 또는 -1 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1625&quot; data-start=&quot;1589&quot;&gt;모든 targets에 대한 처리 결과를 리스트 형태로 반환&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>코딩 테스트 연습/[프로그래머스] Python</category>
      <author>duswjd_data</author>
      <guid isPermaLink="true">https://duswjd00.tistory.com/132</guid>
      <comments>https://duswjd00.tistory.com/132#entry132comment</comments>
      <pubDate>Wed, 27 Aug 2025 10:09:09 +0900</pubDate>
    </item>
  </channel>
</rss>