<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>몸과 마음이 건전한 SW 개발자</title>
    <link>https://sound-programming.tistory.com/</link>
    <description> 풀스택 개발자가 되기 위해 경험한 것들을 기록합니다.
몸과 마음이 건전한 개발자가 되어 여러 사람들에게 선한 영향력을 끼치는 사람이 되고 싶습니다.</description>
    <language>ko</language>
    <pubDate>Wed, 8 Jul 2026 23:17:30 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>스위태니</managingEditor>
    <image>
      <title>몸과 마음이 건전한 SW 개발자</title>
      <url>https://tistory1.daumcdn.net/tistory/6275791/attach/e85e2c5474d44a26ae4cbecfe7a04288</url>
      <link>https://sound-programming.tistory.com</link>
    </image>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 Basic Join - Top Competitors</title>
      <link>https://sound-programming.tistory.com/477</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/full-score/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/full-score/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776846460769&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;Top Competitors | HackerRank&quot; data-og-description=&quot;Query a list of top-scoring hackers.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/full-score/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/full-score/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bCeaKh/dJMb8YXNQhc/rfhglq2Of4a9nhbYcktQOK/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/full-score/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/full-score/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bCeaKh/dJMb8YXNQhc/rfhglq2Of4a9nhbYcktQOK/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Top Competitors | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query a list of top-scoring hackers.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select H.hacker_id, H.name from submissions as S
join challenges as C on S.challenge_id = C.challenge_id 
join difficulty as D on C.difficulty_level = D.difficulty_level
join hackers as H on H.hacker_id = S.hacker_id
where S.score = D.score
group by H.hacker_id, H.name having count(*) &amp;gt;= 2
order by count(*) desc, H.hacker_id asc;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;3,0,0&quot;&gt;데이터 결합(Join)&lt;/b&gt;: 먼저 제출 이력(Submissions), 문제 정보(Challenges), 난이도(Difficulty), 해커 정보(Hackers) 테이블을 모두 연결하여 하나의 거대한 데이터 세트를 만든다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;3,1,0&quot;&gt;난이도별 만점 기준 확인&lt;/b&gt;: Challenges와 Difficulty 테이블을 조인함으로써, 각 문제의 난이도 레벨에 해당하는 최고 점수(D.score)가 얼마인지 식별한다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;3,2,0&quot;&gt;만점 여부 필터링(Where)&lt;/b&gt;: WHERE S.score = D.score 조건을 통해, 해커가 획득한 점수가 해당 문제의 최고 점수와 일치하는 '만점 제출건'만 남긴다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;3,3,0&quot;&gt;해커별 그룹화(Group By)&lt;/b&gt;: 만점을 받은 기록들을 해커의 ID와 이름별로 묶어, 해커 한 명당 몇 개의 만점을 기록했는지 계산할 준비한다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;3,4,0&quot;&gt;2회 이상 달성자 선별(Having)&lt;/b&gt;: HAVING count(*) &amp;gt;= 2 구문을 사용하여 만점 횟수가 2회 이상인 실력파 해커들만 최종적으로 필터링한다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;3,5,0&quot;&gt;결과 정렬(Order By)&lt;/b&gt;: 만점을 많이 받은 순서(내림차순)로 먼저 정렬하고, 횟수가 같다면 해커 ID(오름차순) 순으로 정렬하여 결과를 출력한다.&lt;/li&gt;
&lt;/ol&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;873&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v6q8A/dJMcaaLOlkX/QfnDFXmpgWaNsGoJ7Oiq9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v6q8A/dJMcaaLOlkX/QfnDFXmpgWaNsGoJ7Oiq9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v6q8A/dJMcaaLOlkX/QfnDFXmpgWaNsGoJ7Oiq9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv6q8A%2FdJMcaaLOlkX%2FQfnDFXmpgWaNsGoJ7Oiq9K%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;833&quot; height=&quot;873&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;873&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>count</category>
      <category>group by</category>
      <category>HackerRank</category>
      <category>HAVING</category>
      <category>join</category>
      <category>MSsql</category>
      <category>order by</category>
      <category>SQL</category>
      <category>조인</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/477</guid>
      <comments>https://sound-programming.tistory.com/477#entry477comment</comments>
      <pubDate>Thu, 23 Apr 2026 08:21:31 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 Basic Join - The Report</title>
      <link>https://sound-programming.tistory.com/476</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/the-report/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/the-report/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776748374746&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;The Report | HackerRank&quot; data-og-description=&quot;Write a query to generate a report containing three columns: Name, Grade and Mark.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/the-report/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/the-report/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bT0CaB/dJMb9frHBIj/dgkNOfRLOpuxeXBv2qmdd0/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/the-report/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/the-report/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bT0CaB/dJMb9frHBIj/dgkNOfRLOpuxeXBv2qmdd0/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;The Report | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Write a query to generate a report containing three columns: Name, Grade and Mark.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776748394815&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select if(gra.grade &amp;gt;= 8, stu.name, null), gra.grade, stu.marks from students as stu
left join grades as gra on stu.marks &amp;gt;= gra.min_mark and stu.marks &amp;lt;= gra.max_mark
order by gra.grade desc, stu.name;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    CASE 
        WHEN G.Grade &amp;gt;= 8 THEN S.Name 
        ELSE NULL 
    END AS Name, 
    G.Grade, 
    S.Marks
FROM Students S
JOIN Grades G ON S.Marks BETWEEN G.Min_Mark AND G.Max_Mark
ORDER BY 
    G.Grade DESC, 
    CASE WHEN G.Grade &amp;gt;= 8 THEN S.Name END ASC,
    CASE WHEN G.Grade &amp;lt; 8 THEN S.Marks END ASC;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일단 8등급 이하 학생은 null로 보여주려고 했다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;근데 IF가 없고 여기서는 CASE END와 그 속에서 WHEN THEN ELSE를 써야했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;조인은 잘 했는데 정렬을 틀렸다.&lt;/li&gt;
&lt;li&gt;등급 순 내림차순으로 정렬하고
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;8등급 이상은 이름 + 오름차순&lt;/li&gt;
&lt;li&gt;8등급 미만은 점수 + 오름차순&lt;/li&gt;
&lt;li&gt;으로 정렬해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XMMri/dJMcagrGOvW/fUnq2BSlqCimNfmMZ2wgok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XMMri/dJMcagrGOvW/fUnq2BSlqCimNfmMZ2wgok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XMMri/dJMcagrGOvW/fUnq2BSlqCimNfmMZ2wgok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXMMri%2FdJMcagrGOvW%2FfUnq2BSlqCimNfmMZ2wgok%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;893&quot; data-origin-width=&quot;1011&quot; data-origin-height=&quot;893&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;when then else case end 봤지만 쓸줄 모른다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>basic join</category>
      <category>Case</category>
      <category>Else</category>
      <category>End</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>SQL</category>
      <category>Then</category>
      <category>When</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/476</guid>
      <comments>https://sound-programming.tistory.com/476#entry476comment</comments>
      <pubDate>Tue, 21 Apr 2026 14:20:09 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 Basic Join - Average Population of Each Continent</title>
      <link>https://sound-programming.tistory.com/475</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/average-population-of-each-continent/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/average-population-of-each-continent/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776745787733&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;Average Population of Each Continent | HackerRank&quot; data-og-description=&quot;Query the names of all continents and their respective city populations, rounded down to the nearest integer.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/average-population-of-each-continent/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/average-population-of-each-continent/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/tNPkQ/dJMb8TCbNgu/RkJWkOw8IdMv9K1FXOFk20/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/average-population-of-each-continent/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/average-population-of-each-continent/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/tNPkQ/dJMb8TCbNgu/RkJWkOw8IdMv9K1FXOFk20/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Average Population of Each Continent | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query the names of all continents and their respective city populations, rounded down to the nearest integer.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드 1&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776746416811&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select co.continent, floor(avg(ci.population)) from city as ci 
left join country as co on ci.countrycode = co.code 
group by co.continent;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mzYQN/dJMcagyro03/Bkztsi4XcoAuhukFHG5ir1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mzYQN/dJMcagyro03/Bkztsi4XcoAuhukFHG5ir1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mzYQN/dJMcagyro03/Bkztsi4XcoAuhukFHG5ir1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmzYQN%2FdJMcagyro03%2FBkztsi4XcoAuhukFHG5ir1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;467&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드 2&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776745897461&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select co.continent, floor(avg(ci.population)) from city as ci 
right join country as co on ci.countrycode = co.code 
group by co.continent;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mROjF/dJMcagL1mll/7RdKv26xCje0VJY7j9bFP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mROjF/dJMcagL1mll/7RdKv26xCje0VJY7j9bFP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mROjF/dJMcagL1mll/7RdKv26xCje0VJY7j9bFP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmROjF%2FdJMcagL1mll%2F7RdKv26xCje0VJY7j9bFP1%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;342&quot; height=&quot;506&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    CO.Continent, 
    FLOOR(AVG(CI.Population))
FROM CITY AS CI
INNER JOIN COUNTRY AS CO 
    ON CI.CountryCode = CO.Code
GROUP BY CO.Continent;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 문제 해결 사고 과정&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;4&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,0,0&quot;&gt;연결(Join):&lt;/b&gt; CITY 테이블에는 인구 정보가 있고, COUNTRY 테이블에는 대륙 정보가 있습니다. 두 테이블을 CountryCode와 Code를 기준으로 합쳐야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,1,0&quot;&gt;그룹화(Group By):&lt;/b&gt; 대륙별 평균을 구해야 하므로 Continent 컬럼을 기준으로 데이터를 묶습니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,2,0&quot;&gt;계산(Average):&lt;/b&gt; AVG(Population)를 사용하여 인구 평균을 구합니다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;4,3,0&quot;&gt;내림(Floor &amp;amp; Integer):&lt;/b&gt; 소수점을 버리고(내림) 결과값을 정수(Integer) 형태로 출력해야 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwiRmajQ1_2TAxUAAAAAHQAAAAAQqQI&quot; data-hveid=&quot;0&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-path-to-node=&quot;9&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 주요 오답 포인트 및 정리&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;10&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10,0,0&quot;&gt;왜 INNER JOIN?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;10,0,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도시가 있는 국가와 대륙만 계산하면 되기 때문. 만약 RIGHT JOIN을 써서 도시가 없는 대륙까지 나오면 평균값이 NULL이 되어 오답 처리가 될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10,1,0&quot;&gt;왜 CAST(... AS FLOAT)?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;10,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSSQL에서 INT / INT를 하면 결과도 정수형이 되어 소수점이 미리 잘려나갈 수 있다. 정확한 평균 계산 후 내림을 하기 위해 잠시 실수형(FLOAT)으로 변환하는 것이 안전&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;10,2,0&quot;&gt;왜 FLOOR?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;10,2,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제에서 요구한 &lt;b&gt;'Rounded down'&lt;/b&gt;에 가장 부합하는 함수. (소수점 첫째 자리에서 무조건 내림)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;835&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lYOGs/dJMcahc38Mc/OYO62g0wdpvojr4ciJUx91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lYOGs/dJMcahc38Mc/OYO62g0wdpvojr4ciJUx91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lYOGs/dJMcahc38Mc/OYO62g0wdpvojr4ciJUx91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlYOGs%2FdJMcahc38Mc%2FOYO62g0wdpvojr4ciJUx91%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;643&quot; height=&quot;835&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;835&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;left join을 해버리면 대륙이 명시되지 않은 데이터를 가져와서 null로 보여진다.&lt;/li&gt;
&lt;li&gt;right join을 하면 도시에 인구수가 명시되지 않은 데이터까지 avg를 하기 때문에 null이 나온다.&lt;/li&gt;
&lt;li&gt;따라서 둘 다 있는 inner join으로 문제를 풀어야 한다.&lt;/li&gt;
&lt;li&gt;데이터가 어떻게 생겼는지를 모르니 풀기가 좀 까다로웠다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>AVG</category>
      <category>Floor</category>
      <category>HackerRank</category>
      <category>Inner</category>
      <category>join</category>
      <category>LEFT</category>
      <category>MSsql</category>
      <category>right</category>
      <category>SQL</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/475</guid>
      <comments>https://sound-programming.tistory.com/475#entry475comment</comments>
      <pubDate>Tue, 21 Apr 2026 13:44:30 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 Aggregation Weather Observation Station 14</title>
      <link>https://sound-programming.tistory.com/474</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-14/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-14/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776740259300&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;Weather Observation Station 14 | HackerRank&quot; data-og-description=&quot;Query the greatest value of the Northern Latitudes from STATION that are under 137.2345 and truncated to 4 decimal places.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-14/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-14/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cbwY3h/dJMb8XR7OUp/tBvrqAcsznyfAfPdKxmb01/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-14/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-14/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cbwY3h/dJMb8XR7OUp/tBvrqAcsznyfAfPdKxmb01/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 14 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query the greatest value of the Northern Latitudes from STATION that are under 137.2345 and truncated to 4 decimal places.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select top(1) cast(lat_n as decimal(10, 4)) from station
where lat_n &amp;lt; 137.2345
order by lat_n desc;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;703&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqzBcK/dJMb990rhQE/5qScCksS4GV5gBqnBZsJwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqzBcK/dJMb990rhQE/5qScCksS4GV5gBqnBZsJwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqzBcK/dJMb990rhQE/5qScCksS4GV5gBqnBZsJwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqzBcK%2FdJMb990rhQE%2F5qScCksS4GV5gBqnBZsJwK%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;975&quot; height=&quot;703&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;703&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>SQL/MSSQL</category>
      <category>aggregation</category>
      <category>cast</category>
      <category>decimal</category>
      <category>desc</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>order by</category>
      <category>SQL</category>
      <category>Top</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/474</guid>
      <comments>https://sound-programming.tistory.com/474#entry474comment</comments>
      <pubDate>Tue, 21 Apr 2026 11:58:45 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 Aggregation Weather Observation Station 13</title>
      <link>https://sound-programming.tistory.com/473</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-13/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-13/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776739808445&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;Weather Observation Station 13 | HackerRank&quot; data-og-description=&quot;Query the sum of Northern Latitudes having values greater than 38.7880 and less than 137.2345, truncated to 4 decimal places.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-13/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-13/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9Fgcj/dJMb8955KMQ/O05we3WjURnqSUhRyDD2K1/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-13/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-13/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9Fgcj/dJMb8955KMQ/O05we3WjURnqSUhRyDD2K1/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 13 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query the sum of Northern Latitudes having values greater than 38.7880 and less than 137.2345, truncated to 4 decimal places.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CAST(SUM(LAT_N) AS DECIMAL(10, 4))
FROM STATION 
WHERE LAT_N &amp;gt; 38.7880 AND LAT_N &amp;lt; 137.2345;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfgwln/dJMcaaE2vBX/PnehzSYAL2w8iYqsRvmjAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfgwln/dJMcaaE2vBX/PnehzSYAL2w8iYqsRvmjAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfgwln/dJMcaaE2vBX/PnehzSYAL2w8iYqsRvmjAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcfgwln%2FdJMcaaE2vBX%2FPnehzSYAL2w8iYqsRvmjAK%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;989&quot; height=&quot;694&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MS SQL Server에는 TRUNCATE라는 함수가 따로 없다.&lt;/li&gt;
&lt;li&gt;대신 ROUND 함수의 세 번째 인자를 활용하거나 CAST를 사용해야 한다.&lt;/li&gt;
&lt;li&gt;하지만 round의 경우 해당 자리에서 자를 뿐이지 00은 원본만큼 보여준다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;round(1234.1234, 1)&lt;/li&gt;
&lt;li&gt;1234.1000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;따라서 cast나 format을 써야하는데 format이 느리기 때문에 일부러 cast를 사용했다.&lt;/li&gt;
&lt;li&gt;숫자가 너무 큰 경우 format을 사용해야 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>aggregation</category>
      <category>cast</category>
      <category>decimal</category>
      <category>Format</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>Round</category>
      <category>SQL</category>
      <category>TRUNCATE</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/473</guid>
      <comments>https://sound-programming.tistory.com/473#entry473comment</comments>
      <pubDate>Tue, 21 Apr 2026 11:54:18 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 Aggregation Weather Observation Station 2 (Cast, Decimal, Format, Round, N, F)</title>
      <link>https://sound-programming.tistory.com/472</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-2/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-2/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776737825935&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;Weather Observation Station 2 | HackerRank&quot; data-og-description=&quot;Write a query to print the sum of LAT_N and the sum of LONG_W separated by space, rounded to 2 decimal places.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-2/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-2/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3pJSe/dJMb84qaMH1/PcerkA9XrVNDuyaZGg0YKk/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-2/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-2/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3pJSe/dJMb84qaMH1/PcerkA9XrVNDuyaZGg0YKk/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 2 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Write a query to print the sum of LAT_N and the sum of LONG_W separated by space, rounded to 2 decimal places.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드 1&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776737815436&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ROUND(SUM(LAT_N), 2), ROUND(SUM(LONG_W), 2) FROM STATION;&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;b&gt;틀린 코드 2&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776738181311&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CAST(SUM(LAT_N) AS DECIMAL(10, 2)), CAST(SUM(LONG_W) AS DECIMAL(10, 2)) FROM STATION;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    CAST(SUM(LAT_N) AS DECIMAL(10, 2)), 
    CAST(SUM(LONG_W) AS DECIMAL(10, 2)) 
FROM STATION;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sbll9/dJMcaf0A3ip/JPaOx48SuDh9j2v3pu0GN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sbll9/dJMcaf0A3ip/JPaOx48SuDh9j2v3pu0GN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sbll9/dJMcaf0A3ip/JPaOx48SuDh9j2v3pu0GN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsbll9%2FdJMcaf0A3ip%2FJPaOx48SuDh9j2v3pu0GN1%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;1019&quot; height=&quot;712&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공부하기&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CAST 함수
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 데이터를 저 데이터 형식으로 형변환(Type Conversion)해라&lt;/li&gt;
&lt;li&gt;CAST(대상 AS 바꿀데이터타입)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DECIMAL(p, s)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;decimal(10, 2)&lt;/li&gt;
&lt;li&gt;precision, 정밀도
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;10&amp;nbsp;&lt;/li&gt;
&lt;li&gt;소수점 앞뒤를 모두 포함한 전체 숫자의 개수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;scale, 스케일
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2&lt;/li&gt;
&lt;li&gt;소수점 아래 몇 번째 자리까지 표현할 것인지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;round와의 차이
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;round는 반올림만 해주고 소수점은 원본만큼 보여줌
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;round (12.1314, 1)&lt;/li&gt;
&lt;li&gt;12.1000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;decimal은 반올림 자동&lt;/li&gt;
&lt;li&gt;소수점 자릿수도 딱 n자리로 고정해서 보여준다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cast(123.4567 as decimal(10, 2))&lt;/li&gt;
&lt;li&gt;123.46&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Format
&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;천 단위 콤마 = N
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N2는 1,234.56처럼 콤마를 찍지만, F2는 1234.56으로 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F는 고정 소수점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fixed-point&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;하지만,,,&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CAST는 매우 빠르고, FORMAT은 상대적으로 꽤 느리다.&lt;/li&gt;
&lt;li&gt;성능에서 차이가 올 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>aggregation</category>
      <category>cast</category>
      <category>decimal</category>
      <category>Format</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>Round</category>
      <category>SQL</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/472</guid>
      <comments>https://sound-programming.tistory.com/472#entry472comment</comments>
      <pubDate>Tue, 21 Apr 2026 11:42:19 +0900</pubDate>
    </item>
    <item>
      <title>[MSSQL] Microsoft SQL Server, SQL Server Management Studio 빠르게 설치하기 (2026년 4월 20일 최신)</title>
      <link>https://sound-programming.tistory.com/471</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;lt; 내용 &amp;gt;&amp;nbsp;&lt;/b&gt;&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;Microsoft SQL Server와 SQL Server Management Studio를 설치하고 실행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&amp;nbsp;&amp;lt; 목차 &amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Microsoft SQL Server 설치&lt;/li&gt;
&lt;li&gt;Server Management Studio 설치&lt;/li&gt;
&lt;li&gt;데이터베이스 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;1. Microsoft SQL Server 설치&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;1033&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm26SI/dJMcafzyYyB/v3sZtAtWH3O1lIEgZ4OuQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm26SI/dJMcafzyYyB/v3sZtAtWH3O1lIEgZ4OuQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm26SI/dJMcafzyYyB/v3sZtAtWH3O1lIEgZ4OuQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm26SI%2FdJMcafzyYyB%2Fv3sZtAtWH3O1lIEgZ4OuQ0%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;1356&quot; height=&quot;1033&quot; data-origin-width=&quot;1356&quot; data-origin-height=&quot;1033&quot;/&gt;&lt;/span&gt;&lt;/figure&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2025 개발자도 무료이고 필자는 Enterprise로 설치해봤다.&lt;/li&gt;
&lt;li&gt;다운로드 받고 더블클릭한 뒤 Basic 클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1776672685343&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;SQL Server 다운로드 | Microsoft&quot; data-og-description=&quot;지금 Microsoft SQL Server 다운로드를 시작하세요. 내 데이터와 워크로드에 가장 적합한 SQL Server 체험판 또는 버전, 에디션, 도구 또는 커넥터를 선택하세요.&quot; data-og-host=&quot;www.microsoft.com&quot; data-og-source-url=&quot;https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads&quot; data-og-url=&quot;https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8Ku18/dJMb8XR7JhQ/oVPMsB9UkNVWZi6FTKCkN0/img.jpg?width=2000&amp;amp;height=803&amp;amp;face=0_0_2000_803,https://scrap.kakaocdn.net/dn/eygzMx/dJMb8T91xCF/GlqzTaXg9cjgxaw9a9ix31/img.jpg?width=2000&amp;amp;height=725&amp;amp;face=1265_131_1474_359,https://scrap.kakaocdn.net/dn/Z4UtY/dJMb8Z3tkU6/EKjr7MioMBWm7zViw4ZJo0/img.jpg?width=1000&amp;amp;height=750&amp;amp;face=556_367_743_554&quot;&gt;&lt;a href=&quot;https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.microsoft.com/ko-kr/sql-server/sql-server-downloads&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8Ku18/dJMb8XR7JhQ/oVPMsB9UkNVWZi6FTKCkN0/img.jpg?width=2000&amp;amp;height=803&amp;amp;face=0_0_2000_803,https://scrap.kakaocdn.net/dn/eygzMx/dJMb8T91xCF/GlqzTaXg9cjgxaw9a9ix31/img.jpg?width=2000&amp;amp;height=725&amp;amp;face=1265_131_1474_359,https://scrap.kakaocdn.net/dn/Z4UtY/dJMb8Z3tkU6/EKjr7MioMBWm7zViw4ZJo0/img.jpg?width=1000&amp;amp;height=750&amp;amp;face=556_367_743_554');&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;SQL Server 다운로드 | Microsoft&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;지금 Microsoft SQL Server 다운로드를 시작하세요. 내 데이터와 워크로드에 가장 적합한 SQL Server 체험판 또는 버전, 에디션, 도구 또는 커넥터를 선택하세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.microsoft.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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cu6Y5v/dJMcaiJLprl/maD8CSzA1yB7dOpmhQSIK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cu6Y5v/dJMcaiJLprl/maD8CSzA1yB7dOpmhQSIK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cu6Y5v/dJMcaiJLprl/maD8CSzA1yB7dOpmhQSIK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcu6Y5v%2FdJMcaiJLprl%2FmaD8CSzA1yB7dOpmhQSIK1%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;853&quot; height=&quot;678&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;680&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFpTHU/dJMcahD6FfC/SQH3bB4GMN4vCZUBIW5J7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFpTHU/dJMcahD6FfC/SQH3bB4GMN4vCZUBIW5J7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFpTHU/dJMcahD6FfC/SQH3bB4GMN4vCZUBIW5J7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFpTHU%2FdJMcahD6FfC%2FSQH3bB4GMN4vCZUBIW5J7K%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;850&quot; height=&quot;680&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;680&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ENXiC/dJMcacbKImw/bbseL1n7zKHkv8uSzc6vlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ENXiC/dJMcacbKImw/bbseL1n7zKHkv8uSzc6vlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ENXiC/dJMcacbKImw/bbseL1n7zKHkv8uSzc6vlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FENXiC%2FdJMcacbKImw%2FbbseL1n7zKHkv8uSzc6vlk%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;852&quot; height=&quot;676&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmMlbN/dJMcaf0AFVC/hwhqwrdLhu1tfBga5eZwN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmMlbN/dJMcaf0AFVC/hwhqwrdLhu1tfBga5eZwN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmMlbN/dJMcaf0AFVC/hwhqwrdLhu1tfBga5eZwN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmMlbN%2FdJMcaf0AFVC%2FhwhqwrdLhu1tfBga5eZwN1%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;852&quot; height=&quot;677&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;/figure&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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8FC9U/dJMcagL0Npq/jzbqfOdsrLPN6hbcJHr7Zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8FC9U/dJMcagL0Npq/jzbqfOdsrLPN6hbcJHr7Zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8FC9U/dJMcagL0Npq/jzbqfOdsrLPN6hbcJHr7Zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8FC9U%2FdJMcagL0Npq%2FjzbqfOdsrLPN6hbcJHr7Zk%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;851&quot; height=&quot;676&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 확인해야 하는 것이 로컬에 새로 설치된 db의 이름&lt;/li&gt;
&lt;li&gt;MSSQLSERVER02
&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;꼭 기억할 것&lt;/b&gt;&lt;/span&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: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;2. Server Management Studio 설치&amp;nbsp;&lt;/b&gt;&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;Install SSMS 클릭하면 다음 화면이 뜸
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 링크
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/ssms/install/install?redirectedfrom=MSDN&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/ssms/install/install?redirectedfrom=MSDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1776672728168&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;SQL Server Management Studio 설치&quot; data-og-description=&quot;Visual Studio 설치 관리자를 사용하여 SSMS(SQL Server Management Studio)를 설치하는 방법을 알아봅니다.&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/ssms/install/install?redirectedfrom=MSDN&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/ssms/install/install&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/PGXaP/dJMb8XR7Jie/1OgUo0pFlngHyz3ZkWr8I0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cucXbj/dJMb8PGyaka/Wu1OaMSMEAbphwJEiXD66k/img.png?width=1236&amp;amp;height=601&amp;amp;face=0_0_1236_601&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/ssms/install/install?redirectedfrom=MSDN&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/ssms/install/install?redirectedfrom=MSDN&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/PGXaP/dJMb8XR7Jie/1OgUo0pFlngHyz3ZkWr8I0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cucXbj/dJMb8PGyaka/Wu1OaMSMEAbphwJEiXD66k/img.png?width=1236&amp;amp;height=601&amp;amp;face=0_0_1236_601');&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;SQL Server Management Studio 설치&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Visual Studio 설치 관리자를 사용하여 SSMS(SQL Server Management Studio)를 설치하는 방법을 알아봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceLHC2/dJMcadIr8wQ/LOjjTBCnymV2NebzrEiit0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceLHC2/dJMcadIr8wQ/LOjjTBCnymV2NebzrEiit0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceLHC2/dJMcadIr8wQ/LOjjTBCnymV2NebzrEiit0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceLHC2%2FdJMcadIr8wQ%2FLOjjTBCnymV2NebzrEiit0%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;882&quot; height=&quot;364&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vs_SSMS 파일 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;641&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sxR9g/dJMcaadW1pG/5cKNoED01khv0DiCE3VWz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sxR9g/dJMcaadW1pG/5cKNoED01khv0DiCE3VWz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sxR9g/dJMcaadW1pG/5cKNoED01khv0DiCE3VWz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsxR9g%2FdJMcaadW1pG%2F5cKNoED01khv0DiCE3VWz0%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;1145&quot; height=&quot;641&quot; data-origin-width=&quot;1145&quot; data-origin-height=&quot;641&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lCu1Z/dJMcahqBX1s/PWraP6krLkgwAe5hf1w3C0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lCu1Z/dJMcahqBX1s/PWraP6krLkgwAe5hf1w3C0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lCu1Z/dJMcahqBX1s/PWraP6krLkgwAe5hf1w3C0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCu1Z%2FdJMcahqBX1s%2FPWraP6krLkgwAe5hf1w3C0%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;486&quot; height=&quot;287&quot; data-origin-width=&quot;486&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vj8DH/dJMcahYqthb/GLFBNtUdcZDkrgBf6d22Zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vj8DH/dJMcahYqthb/GLFBNtUdcZDkrgBf6d22Zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vj8DH/dJMcahYqthb/GLFBNtUdcZDkrgBf6d22Zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvj8DH%2FdJMcahYqthb%2FGLFBNtUdcZDkrgBf6d22Zk%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;490&quot; height=&quot;289&quot; data-origin-width=&quot;490&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;729&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caEORj/dJMcaiwe4N4/X71QeUbI0fcL5KVbODfW4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caEORj/dJMcaiwe4N4/X71QeUbI0fcL5KVbODfW4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caEORj/dJMcaiwe4N4/X71QeUbI0fcL5KVbODfW4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaEORj%2FdJMcaiwe4N4%2FX71QeUbI0fcL5KVbODfW4k%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;1289&quot; height=&quot;729&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;729&quot;/&gt;&lt;/span&gt;&lt;/figure&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2VoY9/dJMcaibZKNb/SO9IW85rl0yTJx3gguP101/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2VoY9/dJMcaibZKNb/SO9IW85rl0yTJx3gguP101/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2VoY9/dJMcaibZKNb/SO9IW85rl0yTJx3gguP101/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2VoY9%2FdJMcaibZKNb%2FSO9IW85rl0yTJx3gguP101%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;1291&quot; height=&quot;738&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;727&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/piZ6B/dJMcadBEcMv/YP0XS2k7RiGqRNadhUNYE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/piZ6B/dJMcadBEcMv/YP0XS2k7RiGqRNadhUNYE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/piZ6B/dJMcadBEcMv/YP0XS2k7RiGqRNadhUNYE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpiZ6B%2FdJMcadBEcMv%2FYP0XS2k7RiGqRNadhUNYE0%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;1289&quot; height=&quot;727&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;727&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kGRmK/dJMcaaSyOH0/vEuWXHOzXIKl9l7lIkLr5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kGRmK/dJMcaaSyOH0/vEuWXHOzXIKl9l7lIkLr5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kGRmK/dJMcaaSyOH0/vEuWXHOzXIKl9l7lIkLr5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkGRmK%2FdJMcaaSyOH0%2FvEuWXHOzXIKl9l7lIkLr5K%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;1289&quot; height=&quot;726&quot; data-origin-width=&quot;1289&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bprEU5/dJMcaaSyOJe/QabLeNNY8e7ZRTf0jk6Zjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bprEU5/dJMcaaSyOJe/QabLeNNY8e7ZRTf0jk6Zjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bprEU5/dJMcaaSyOJe/QabLeNNY8e7ZRTf0jk6Zjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbprEU5%2FdJMcaaSyOJe%2FQabLeNNY8e7ZRTf0jk6Zjk%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;983&quot; height=&quot;507&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;507&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T27rI/dJMcac3RLZO/fCNKQRMbKSOrEvsDR4Kx70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T27rI/dJMcac3RLZO/fCNKQRMbKSOrEvsDR4Kx70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T27rI/dJMcac3RLZO/fCNKQRMbKSOrEvsDR4Kx70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT27rI%2FdJMcac3RLZO%2FfCNKQRMbKSOrEvsDR4Kx70%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;531&quot; height=&quot;642&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필자는 MSSQLSERVER02&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;windows 인증 선택&lt;/li&gt;
&lt;li&gt;서버 인증서 신뢰 꼭 선택&lt;/li&gt;
&lt;li&gt;연결 클릭&lt;/li&gt;
&lt;li&gt;혹시나 이렇게 해도 안되면
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;윈도우 - 시스템 - 설정에서 microsoft 로그인 안되어 있거나&lt;/li&gt;
&lt;li&gt;pin 번호 (윈도우 부팅 후 접속 전에 비밀번호 치게 하는 거) 걸려 있지 않아서 그럴 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;3. 데이터베이스 생성&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4BDcY/dJMcahqBYDa/4lKyFxcJRcDhbkSm80r5zk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4BDcY/dJMcahqBYDa/4lKyFxcJRcDhbkSm80r5zk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4BDcY/dJMcahqBYDa/4lKyFxcJRcDhbkSm80r5zk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4BDcY%2FdJMcahqBYDa%2F4lKyFxcJRcDhbkSm80r5zk%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;424&quot; height=&quot;535&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvDo48/dJMcagrGb38/rtNuFdNgQNkeNyGexAqAn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvDo48/dJMcagrGb38/rtNuFdNgQNkeNyGexAqAn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvDo48/dJMcagrGb38/rtNuFdNgQNkeNyGexAqAn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvDo48%2FdJMcagrGb38%2FrtNuFdNgQNkeNyGexAqAn0%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;838&quot; height=&quot;624&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;db 이름 설정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필자는 MYDB1으로 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;새로고침(똥글뱅이) 눌러보면 MYDB1 생성된 것 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXGyNi/dJMcabDU6sF/1UyQSgOaRaWp1mmqAlXIYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXGyNi/dJMcabDU6sF/1UyQSgOaRaWp1mmqAlXIYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXGyNi/dJMcabDU6sF/1UyQSgOaRaWp1mmqAlXIYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXGyNi%2FdJMcabDU6sF%2F1UyQSgOaRaWp1mmqAlXIYk%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;344&quot; height=&quot;282&quot; data-origin-width=&quot;344&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxizJ5/dJMcaaLMGnH/YwJyotmmT9AGyQ9wCHAiHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxizJ5/dJMcaaLMGnH/YwJyotmmT9AGyQ9wCHAiHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxizJ5/dJMcaaLMGnH/YwJyotmmT9AGyQ9wCHAiHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxizJ5%2FdJMcaaLMGnH%2FYwJyotmmT9AGyQ9wCHAiHK%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;355&quot; height=&quot;537&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&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;</description>
      <category>SQL/MSSQL</category>
      <category>db</category>
      <category>Microsoft SQL Server</category>
      <category>MSsql</category>
      <category>mssql install</category>
      <category>MSSQL설치</category>
      <category>SQL Server Management Studio</category>
      <category>ssms</category>
      <category>데이터베이스</category>
      <category>최신 버전</category>
      <category>쿼리</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/471</guid>
      <comments>https://sound-programming.tistory.com/471#entry471comment</comments>
      <pubDate>Mon, 20 Apr 2026 17:32:05 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 basic select Weather Observation Station 11</title>
      <link>https://sound-programming.tistory.com/470</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-11/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-11/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776401889063&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;Weather Observation Station 11 | HackerRank&quot; data-og-description=&quot;Query a list of CITY names not starting or ending with vowels.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-11/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-11/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/roOwv/dJMb8XR7oaV/l9ngLJpSDS6kVsu1S3KNI0/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-11/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-11/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/roOwv/dJMb8XR7oaV/l9ngLJpSDS6kVsu1S3KNI0/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 11 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query a list of CITY names not starting or ending with vowels.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct city from station where city not like '[aeiou]%[aeiou]';&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;city의 앞 문자가 a e i o u로 시작하지 않고 뒷 문자가 a e i o u로 끝나지 않고 라는 명제가 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;'[^aeiou]%' and '%[^aeiou]'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 명제를 대우로 표현하면 a e i o u로 시작하고 a e i o u로 끝나는 city가 된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;'[aeiou]%[aeiou]'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;위의 대우 명제를 not like로 부정하면&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;not like '[aeiou]%[aeiou]'가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lYiXb/dJMcaaSwTiR/ZKRyUjG5tqBlgKbGKJz661/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lYiXb/dJMcaaSwTiR/ZKRyUjG5tqBlgKbGKJz661/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lYiXb/dJMcaaSwTiR/ZKRyUjG5tqBlgKbGKJz661/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlYiXb%2FdJMcaaSwTiR%2FZKRyUjG5tqBlgKbGKJz661%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;831&quot; height=&quot;881&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>RegExp</category>
      <category>SQL</category>
      <category>대우</category>
      <category>명제</category>
      <category>역</category>
      <category>이</category>
      <category>정규표현식</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/470</guid>
      <comments>https://sound-programming.tistory.com/470#entry470comment</comments>
      <pubDate>Fri, 17 Apr 2026 14:04:51 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 basic select Weather Observation Station 8</title>
      <link>https://sound-programming.tistory.com/469</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-8/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-8/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776400427085&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;Weather Observation Station 8 | HackerRank&quot; data-og-description=&quot;Query CITY names that start AND end with vowels.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-8/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-8/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/clCsxd/dJMb84X0raU/hdBktZpBSIKuYH0SAFUHF1/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-8/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-8/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/clCsxd/dJMb84X0raU/hdBktZpBSIKuYH0SAFUHF1/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 8 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query CITY names that start AND end with vowels.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct city from station where city like '[aeiou]%[aeiou]';&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;앞 뒤로 a e i o u가 있는 city를 찾는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;791&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pivgP/dJMcagFdDxZ/210xH9GkfHNFtcVecZWo00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pivgP/dJMcagFdDxZ/210xH9GkfHNFtcVecZWo00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pivgP/dJMcagFdDxZ/210xH9GkfHNFtcVecZWo00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpivgP%2FdJMcagFdDxZ%2F210xH9GkfHNFtcVecZWo00%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;817&quot; height=&quot;791&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;791&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 문제도 마찬가지로 city를 가공해서 풀 수도 있다.&lt;/li&gt;
&lt;li&gt;정규표현식을 사용해서 조금이라도 더 빠르게 성능을 향상시킬 수 있다.&lt;/li&gt;
&lt;li&gt;하지만 데이터 양이 적거나 aeiou로 시작하고 끝나는 나라의 개수가 50% 전후로 차지한다면 의미 없다.&lt;/li&gt;
&lt;li&gt;100% 데이터 중에 25~20% 이하의 데이터를 찾을 때 유용할 것으로 기대한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-path-to-node=&quot;4&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 세 가지 방식 정밀 비교&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;5&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;비교 항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;① NOT LIKE '[aeiou]%'&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;② LIKE '[^aeiou]%'&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;③ LIKE '[bcdf...]%'&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,0,0&quot;&gt;논리 방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,1,0&quot;&gt;부정의 부정&lt;/b&gt; (모음 찾고 제외)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,2,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,2,0&quot;&gt;부정 조건&lt;/b&gt; (모음 제외 필터)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,3,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,3,0&quot;&gt;긍정 조건&lt;/b&gt; (자음 목록 지정)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,0,0&quot;&gt;인덱스 활용&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,1,0&quot;&gt;매우 낮음&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,2,0&quot;&gt;낮음&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,3,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,3,0&quot;&gt;상대적으로 높음 (이론상)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,3,0,0&quot;&gt;쿼리 길이&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,1,0&quot;&gt;짧음 (깔끔)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,2,0&quot;&gt;짧음 (직관적)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,3,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,3,3,0&quot;&gt;매우 김 (복잡)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,4,0,0&quot;&gt;유연성&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,1,0&quot;&gt;숫자/특수문자도 포함됨&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,2,0&quot;&gt;숫자/특수문자도 포함됨&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,3,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,4,3,0&quot;&gt;자음만 딱 골라냄&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부정이 없는 것이 제일 좋지만 ai agent들은 2번을 제일 추천함&lt;/li&gt;
&lt;li&gt;index를 무조건 타야 한다면 3번을 추천&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>RegExp</category>
      <category>SQL</category>
      <category>정규표현식</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/469</guid>
      <comments>https://sound-programming.tistory.com/469#entry469comment</comments>
      <pubDate>Fri, 17 Apr 2026 13:38:48 +0900</pubDate>
    </item>
    <item>
      <title>자주 쓰는 정규 표현식 그리고 LIKE, PATINDEX, REGEXP - 성능 향상을 위해서</title>
      <link>https://sound-programming.tistory.com/468</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Gemini_Generated_Image_2qcvcs2qcvcs2qcv.png&quot; data-origin-width=&quot;2816&quot; data-origin-height=&quot;1536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/72YGv/dJMcadVXvwf/MtQXwKwdzeD68hlnk9rU2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/72YGv/dJMcadVXvwf/MtQXwKwdzeD68hlnk9rU2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/72YGv/dJMcadVXvwf/MtQXwKwdzeD68hlnk9rU2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F72YGv%2FdJMcadVXvwf%2FMtQXwKwdzeD68hlnk9rU2K%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;2816&quot; height=&quot;1536&quot; data-filename=&quot;Gemini_Generated_Image_2qcvcs2qcvcs2qcv.png&quot; data-origin-width=&quot;2816&quot; data-origin-height=&quot;1536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;lt; 내용 &amp;gt;&amp;nbsp;&lt;/b&gt;&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;정규 표현식을 공부하고 사용할 수 있다.&lt;/li&gt;
&lt;li&gt;패턴 매칭을 통해서 성능을 향상할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&amp;nbsp;&amp;lt; 목차 &amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/b&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;기본적으로 알아야 할 패턴&lt;/b&gt;&lt;/li&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;li&gt;&lt;b&gt;LIKE VS PATINDEX&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;REGEXP_LIKE&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정리하기&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;1. 기본적으로 알아야 할 패턴&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 필수: 기본 패턴 (LIKE 연산자)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;가장 기초적이지만 실무 쿼리의 90%를 차지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;5&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,0,0&quot;&gt;%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,1,0&quot;&gt;0개 이상의 모든 문자&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,2,0&quot;&gt;LIKE 'A%'&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,3,0&quot;&gt;'A'로 시작하는 모든 문자열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,0,0&quot;&gt;_&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,1,0&quot;&gt;정확히 1개의 모든 문자&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,2,0&quot;&gt;LIKE 'A_'&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,3,0&quot;&gt;'A'로 시작하는 딱 두 글자 문자열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,0,0&quot;&gt;[]&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,1,0&quot;&gt;대괄호 안의 문자 중 하나&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,2,0&quot;&gt;LIKE '[aeiou]%'&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,3,0&quot;&gt;모음으로 시작하는 문자열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,0,0&quot;&gt;[^]&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,1,0&quot;&gt;대괄호 안의 문자가 아닌 것&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,2,0&quot;&gt;LIKE '[^0-9]%'&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,3,0&quot;&gt;숫자로 시작하지 않는 문자열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 기본: 문자 범위 지정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;특정 범위의 문자를 찾을 때 사용하며, 인덱싱 효율도 나쁘지 않은 편이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,0,0&quot;&gt;알파벳만 포함:&lt;/b&gt; LIKE '[a-zA-Z]%'&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0&quot;&gt;숫자만 포함:&lt;/b&gt; LIKE '[0-9]%'&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,2,0&quot;&gt;특정 범위의 알파벳:&lt;/b&gt; LIKE '[a-d]%' (a, b, c, d로 시작하는 경우)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;11&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 적극 권장: 패턴 조합 (실무 응용)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size16&quot;&gt;실제 업무에서 데이터 정제나 유효성 검사를 할 때 가장 많이 쓰는 형태&lt;/p&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;① 자음으로 시작하고 모음으로 끝나는 데이터&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1776397359225&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CITY 
FROM STATION 
WHERE CITY LIKE '[^aeiou]%[aeiou]';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-path-to-node=&quot;16&quot; data-ke-size=&quot;size18&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 data-path-to-node=&quot;17&quot;&gt;예를 들어 'A'로 시작하고 뒤에 숫자 3자리가 오는 경우:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1776397370730&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CODE 
FROM MY_TABLE 
WHERE CODE LIKE 'A[0-9][0-9][0-9]';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; ③ 연속된 공백이나 특수문자 포함 확인 &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1776397378933&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT NAME 
FROM USERS 
WHERE NAME LIKE '%[ ]%'; -- 공백이 포함된 경우&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-path-to-node=&quot;22&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 응용: PATINDEX (더 정교한 검색)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;23&quot; data-ke-size=&quot;size16&quot;&gt;LIKE만으로는 부족할 때, 특정 패턴이 시작되는 &lt;b data-index-in-node=&quot;28&quot; data-path-to-node=&quot;23&quot;&gt;위치&lt;/b&gt;를 찾아주는 함수&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;24&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;24,0,0&quot;&gt;숫자가 처음 나타나는 위치 찾기:&lt;/b&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT PATINDEX('%[0-9]%', 'ABC123DEF'); -- 결과: 4
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;24,1,0&quot;&gt;한글만 포함된 데이터 찾기 (ASCII 범위 활용):&lt;/b&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- 한글 범위는 데이터베이스 정렬 설정(Collation)에 따라 다를 수 있음
SELECT * FROM PRODUCT WHERE PATINDEX('%[가-힣]%', NAME) &amp;gt; 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;26&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. 심화: REGEXP_LIKE (MSSQL 2022 이상)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;27&quot;&gt;최신 버전의 MSSQL을 사용하신다면, 드디어 다른 DB처럼 표준 정규 표현식을 쓸 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjbvpX02POTAxUAAAAAHQAAAAAQvQI&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;-- 이메일 형식이 대략 맞는지 확인
SELECT EMAIL
FROM USERS
WHERE REGEXP_LIKE(EMAIL, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-path-to-node=&quot;30&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  실무 팁: 성능 최적화 (SARGability)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;31&quot; data-ke-size=&quot;size16&quot;&gt;패턴 매칭을 쓸 때 가장 중요한 규칙 하나만 기억하자.&lt;/p&gt;
&lt;blockquote data-path-to-node=&quot;32&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-path-to-node=&quot;32,0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;32,0&quot;&gt;&quot;와일드카드(%)를 앞에 두지 마라.&quot;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;33&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LIKE 'Apple%': &lt;b data-index-in-node=&quot;15&quot; data-path-to-node=&quot;33,0,0&quot;&gt;인덱스 사용 가능&lt;/b&gt; (A로 시작하는 페이지를 바로 찾아감)&lt;/li&gt;
&lt;li&gt;LIKE '%Apple': &lt;b data-index-in-node=&quot;15&quot; data-path-to-node=&quot;33,1,0&quot;&gt;인덱스 사용 불가&lt;/b&gt; (모든 데이터를 다 읽어서 끝이 Apple인지 확인해야 함)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;34&quot; data-ke-size=&quot;size16&quot;&gt;지금 관리하시는 제조 시스템 DB에서 특정 모델 번호나 시리얼 번호를 조회할 때, 가급적 접두사(Prefix)를 명시하여 검색하는 습관을 들이시면 성능 차이를 확연히 느낄 수 있다.&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-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;2. 정규 표현식 설명&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정규 표현식(Regular Expression)&lt;/b&gt;:&amp;nbsp;특정 패턴을 가진 문자열을 찾기 위한 '약속된 기호'들의 집합&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 와일드카드(Wildcard)란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;카드 게임의 '조커'처럼, &lt;b data-index-in-node=&quot;15&quot; data-path-to-node=&quot;4&quot;&gt;어떤 문자든 대신할 수 있는 만능 기호&lt;/b&gt;를 말한다. SQL의 LIKE 연산자에서 가장 먼저 접하게 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;5&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;비유&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,0,0&quot;&gt;%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,1,0&quot;&gt;퍼센트&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,2,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,2,0&quot;&gt;0개 이상의&lt;/b&gt; 아무 문자&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,3,0&quot;&gt;&quot;이 뒤에 뭐가 오든, 아예 없든 상관없어&quot;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,0,0&quot;&gt;_&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,1,0&quot;&gt;언더바&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,2,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,2,0&quot;&gt;딱 1개의&lt;/b&gt; 아무 문자&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,3,0&quot;&gt;&quot;여기에 글자 하나는 반드시 있어야 해&quot;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6&quot;&gt;예시:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;7&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WHERE NAME LIKE '이%': 이승엽, 이문세, 이선희 (이로 시작하는 모든 것)&lt;/li&gt;
&lt;li&gt;WHERE NAME LIKE '이_': 이산, 이황, 이이 (이로 시작하는 딱 두 글자)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;9&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 정규 표현식 핵심 기호 (표준 &amp;amp; MSSQL 패턴)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;11&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;기능&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,1,0,0&quot;&gt;.&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,1,1,0&quot;&gt;점 (Any)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,2,0&quot;&gt;임의의 &lt;b data-index-in-node=&quot;4&quot; data-path-to-node=&quot;11,1,2,0&quot;&gt;한 글자&lt;/b&gt; (와일드카드의 _와 같음)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,1,3,0&quot;&gt;a.b &amp;rarr; aab, acb, a1b 등&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,2,0,0&quot;&gt;^&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,2,1,0&quot;&gt;삿갓 (Start)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,2,0&quot;&gt;문자열의 &lt;b data-index-in-node=&quot;5&quot; data-path-to-node=&quot;11,2,2,0&quot;&gt;시작&lt;/b&gt;을 의미&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,2,3,0&quot;&gt;^A &amp;rarr; 'A'로 시작하는 문장&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,3,0,0&quot;&gt;$&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,3,1,0&quot;&gt;달러 (End)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,2,0&quot;&gt;문자열의 &lt;b data-index-in-node=&quot;5&quot; data-path-to-node=&quot;11,3,2,0&quot;&gt;끝&lt;/b&gt;을 의미&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,3,3,0&quot;&gt;Z$ &amp;rarr; 'Z'로 끝나는 문장&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,4,0,0&quot;&gt;[]&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,4,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,4,1,0&quot;&gt;대괄호 (Or)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,4,2,0&quot;&gt;괄호 안의 문자 중 &lt;b data-index-in-node=&quot;11&quot; data-path-to-node=&quot;11,4,2,0&quot;&gt;하나라도 일치&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,4,3,0&quot;&gt;[abc] &amp;rarr; a 또는 b 또는 c&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,5,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,5,0,0&quot;&gt;[^]&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,5,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,5,1,0&quot;&gt;부정 (Not)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,5,2,0&quot;&gt;대괄호 안의 문자를 &lt;b data-index-in-node=&quot;11&quot; data-path-to-node=&quot;11,5,2,0&quot;&gt;제외&lt;/b&gt;하고 일치&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,5,3,0&quot;&gt;[^0-9] &amp;rarr; 숫자가 아닌 문자&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,6,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,6,0,0&quot;&gt;-&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,6,1,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,6,1,0&quot;&gt;하이픈 (Range)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,6,2,0&quot;&gt;문자의 &lt;b data-index-in-node=&quot;4&quot; data-path-to-node=&quot;11,6,2,0&quot;&gt;범위&lt;/b&gt;를 지정&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;11,6,3,0&quot;&gt;[a-z] &amp;rarr; 영어 소문자 전체&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-path-to-node=&quot;13&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 수량자 (얼마나 반복되는가?)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;14&quot; data-ke-size=&quot;size16&quot;&gt;기호 뒤에 붙어서 &quot;앞의 패턴이 몇 번이나 나올까?&quot;를 결정한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;15&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,1,0,0&quot;&gt;*&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,1,1,0&quot;&gt;0번 이상&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,1,2,0&quot;&gt;앞의 글자가 없어도 되고, 아주 많아도 됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,2,0,0&quot;&gt;+&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,2,1,0&quot;&gt;1번 이상&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,2,2,0&quot;&gt;앞의 글자가 &lt;b data-index-in-node=&quot;7&quot; data-path-to-node=&quot;15,2,2,0&quot;&gt;최소 1번은 꼭&lt;/b&gt; 나와야 함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,3,0,0&quot;&gt;?&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,3,1,0&quot;&gt;0번 또는 1번&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,3,2,0&quot;&gt;앞의 글자가 있거나 없거나 (선택 사항)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,4,0,0&quot;&gt;{n}&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,4,1,0&quot;&gt;정확히 n번&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,4,2,0&quot;&gt;앞의 패턴이 &lt;b data-index-in-node=&quot;7&quot; data-path-to-node=&quot;15,4,2,0&quot;&gt;정확히 n번&lt;/b&gt; 반복됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,5,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;15,5,0,0&quot;&gt;{n, m}&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,5,1,0&quot;&gt;n번 ~ m번&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;15,5,2,0&quot;&gt;최소 n번에서 최대 m번까지 반복됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;17&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 실제 예시로 이해하기 (SQL 연습용)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;19&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,0,0&quot;&gt;&quot;숫자로 시작하는 것만 찾고 싶어&quot;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;19,0,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패턴: ^[0-9] (시작(^)이 숫자 범위(0-9)인 것)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,1,0&quot;&gt;&quot;전화번호 형식(010-숫자4자리-숫자4자리)을 찾고 싶어&quot;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;19,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패턴: 010-[0-9]{4}-[0-9]{4}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,2,0&quot;&gt;&quot;마지막 글자가 모음(a,e,i,o,u)이 아닌 것만 찾고 싶어&quot;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;19,2,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패턴: [^aeiou]$ (끝($) 부분이 모음이 아닌 것([^]) )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;21&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  주의할 점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;22&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;MSSQL의 LIKE 문법에서는 표준 정규식의 모든 기호(예: +, {})를 다 지원하지는 않는다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;22&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; 대신&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b data-path-to-node=&quot;22&quot; data-index-in-node=&quot;60&quot;&gt;LIKE '[^aeiou]%'&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;처럼 대괄호를 활용한 패턴을 주로 쓴다. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;3. 사이트 추천&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-path-to-node=&quot;1&quot; data-ke-size=&quot;size16&quot;&gt;연습하기 가장 좋고 유명한 사이트 3곳을 추천&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. RegexOne (완전 초보자용 강추 / 영어)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;정규표현식을 아예 모르는 사람을 위해 &lt;b data-index-in-node=&quot;21&quot; data-path-to-node=&quot;4&quot;&gt;레벨 1부터 단계별로 미션을 주는 학습 사이트&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;5&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,0,0&quot;&gt;특징&lt;/b&gt;: &quot;숫자만 골라내 보세요&quot;, &quot;글자 세 개만 골라내 보세요&quot; 같은 문제를 주고, 하단 입력창에 정답을 치면 다음 단계로 넘어간다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,0&quot;&gt;장점&lt;/b&gt;: 설명이 매우 친절하고, 문법을 하나씩 쌓아 올리는 방식이라 정석으로 배우기 좋다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,0&quot;&gt;링크&lt;/b&gt;: &lt;a href=&quot;https://regexone.com/&quot; data-ved=&quot;0CAAQ_4QMahgKEwjbvpX02POTAxUAAAAAHQAAAAAQ_gI&quot; data-hveid=&quot;0&quot;&gt;RegexOne 바로가기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;6&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Regex101 (실전 연습 및 검증용 / 영어)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;정규표현식의 '끝판왕' 사이트. 실제 개발자들이 가장 많이 사용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;8&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,0,0&quot;&gt;특징&lt;/b&gt;: 내가 쓴 정규표현식이 &lt;b data-index-in-node=&quot;16&quot; data-path-to-node=&quot;8,0,0&quot;&gt;어떤 원리로 작동하는지 오른쪽 'Explanation' 창에서 한 줄 한 줄 해석&lt;/b&gt;해 준다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,1,0&quot;&gt;장점&lt;/b&gt;: 내가 가진 데이터(문장들)를 복사해서 붙여넣고, 내가 짠 정규식이 실시간으로 어디를 강조(Highlight)하는지 바로 볼 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;8,2,0&quot;&gt;링크&lt;/b&gt;: &lt;a href=&quot;https://regex101.com/&quot; data-ved=&quot;0CAAQ_4QMahgKEwjbvpX02POTAxUAAAAAHQAAAAAQ_wI&quot; data-hveid=&quot;0&quot;&gt;Regex101 바로가기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;9&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. RegExr (직관적인 인터페이스 / 영어)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;Regex101과 비슷하지만 좀 더 깔끔하고 시각적이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;11&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,0,0&quot;&gt;특징&lt;/b&gt;: 상단 메뉴에 'Cheatsheet'가 있어서, 기호가 기억 안 날 때 옆에서 바로 찾아서 써볼 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,1,0&quot;&gt;장점&lt;/b&gt;: 커뮤니티에서 사람들이 미리 만들어둔 정규식(예: 이메일 체크, 전화번호 체크)을 검색해서 구경할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,2,0&quot;&gt;링크&lt;/b&gt;: &lt;a href=&quot;https://regexr.com/&quot; data-ved=&quot;0CAAQ_4QMahgKEwjbvpX02POTAxUAAAAAHQAAAAAQgAM&quot; data-hveid=&quot;0&quot;&gt;RegExr 바로가기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;13&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  공부하는 팁 (이미지로 흐름 잡기)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;14&quot; data-ke-size=&quot;size16&quot;&gt;정규표현식은 아래 그림처럼 &lt;b&gt;'특정 문자를 가리키는 기호'&lt;/b&gt;와 &lt;b&gt;'그게 몇 번 반복되는지 말하는 기호'&lt;/b&gt;의 조합이라고 생각하시면 편하다.&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;15&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 한글로 배우고 싶다면?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;영어가 부담스럽다면, 웹사이트는 아니지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b data-path-to-node=&quot;16&quot; data-index-in-node=&quot;25&quot;&gt;'점프 투 파이썬 - 정규 표현식'&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;파트를 추천한다. &lt;/span&gt;&lt;/li&gt;
&lt;li data-path-to-node=&quot;16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;파이썬 기반 설명이지만, 정규식 문법 자체는 공통이라 기초 개념을 잡기에 이보다 좋은 한국어 설명이 없다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;17,0,0&quot;&gt;링크&lt;/b&gt;: &lt;a href=&quot;https://www.google.com/search?q=https://wikidocs.net/4311&amp;amp;authuser=1&quot; data-ved=&quot;0CAAQ_4QMahgKEwjbvpX02POTAxUAAAAAHQAAAAAQgQM&quot; data-hveid=&quot;0&quot;&gt;위키독스 - 정규 표현식&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;4. LIKE VS PATINDEX&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. LIKE vs PATINDEX 차이점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;가장 큰 차이는 &lt;b&gt;&quot;찾느냐, 위치를 알려주느냐&quot;&lt;/b&gt;.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;5&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기능&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;LIKE&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;PATINDEX&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,0,0&quot;&gt;결과값&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,1,0&quot;&gt;참/거짓 (맞다/틀리다)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,2,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,2,0&quot;&gt;숫자 (패턴이 시작되는 위치)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,0,0&quot;&gt;주요 용도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,1,0&quot;&gt;데이터 필터링 (WHERE 절)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,2,0&quot;&gt;문자열 자르기, 복잡한 위치 찾기&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,3,0,0&quot;&gt;인덱스 활용&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,1,0&quot;&gt;시작 패턴(A%) 시 활용 가능&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,2,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,3,2,0&quot;&gt;활용 불가 (느림)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;6&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,0,0&quot;&gt;LIKE&lt;/b&gt;: &quot;이 데이터에 '서울'이 포함되어 있어?&quot; (Yes/No)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;6,1,0&quot;&gt;PATINDEX&lt;/b&gt;: &quot;이 데이터에서 '숫자'가 처음 나타나는 게 &lt;b data-index-in-node=&quot;35&quot; data-path-to-node=&quot;6,1,0&quot;&gt;몇 번째 글자&lt;/b&gt;야?&quot; (12번째!)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;8&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. PATINDEX에서 쓸 수 있는 정규표현식 (패턴)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;PATINDEX는 LIKE보다 패턴을 조금 더 유연하게 쓸 수 있지만, 여전히 &lt;b data-index-in-node=&quot;44&quot; data-path-to-node=&quot;9&quot;&gt;MSSQL 표준 패턴&lt;/b&gt;만 지원&lt;/p&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size18&quot;&gt;✅ 쓸 수 있는 것 (LIKE와 비슷함)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;11&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,0,0&quot;&gt;%&lt;/b&gt;: 아무 문자열&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,1,0&quot;&gt;_&lt;/b&gt;: 아무 한 글자&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,2,0&quot;&gt;[]&lt;/b&gt;: 대괄호 안의 문자 중 하나 ([0-9], [a-z], [aeiou])&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;11,3,0&quot;&gt;[^]&lt;/b&gt;: 대괄호 안의 문자가 아닌 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;12&quot; data-ke-size=&quot;size18&quot;&gt;❌ 못 쓰는 것 (표준 정규식 기호)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;13&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,0,0&quot;&gt;*, +, ?&lt;/b&gt;: 수량자 (몇 번 반복되는지 지정 불가)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,1,0&quot;&gt;{n, m}&lt;/b&gt;: 반복 횟수 지정 불가&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,2,0&quot;&gt;|&lt;/b&gt;: OR 연산 (A 또는 B를 |로 구분 불가)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;13,3,0&quot;&gt;()&lt;/b&gt;: 그룹화 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;15&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 왜 PATINDEX를 씀? (실무 예시)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;16&quot;&gt;LIKE로는 도저히 안 될 때 PATINDEX가 구원투수로 등판한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-path-to-node=&quot;17&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-path-to-node=&quot;17,0&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;17,0&quot;&gt;상황: &quot;상품명에서 숫자가 처음 시작되는 부분부터 문자열을 자르고 싶어&quot;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;18&quot;&gt;LIKE는 단순히 &quot;숫자가 있다&quot;만 알려주지만, PATINDEX는 위치를 알려주기 때문에 SUBSTRING 함수와 조합해서 데이터를 가공할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjbvpX02POTAxUAAAAAHQAAAAAQmwM&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;sql&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;-- 'Product_123' 이라는 데이터가 있다면?
-- PATINDEX('%[0-9]%', 'Product_123') -&amp;gt; 결과는 9 (9번째부터 숫자 시작)

SELECT SUBSTRING(ProductName, PATINDEX('%[0-9]%', ProductName), 100)
FROM Products;
-- 이렇게 하면 '123'만 쏙 뽑아낼 수 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-path-to-node=&quot;21&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 요약: 언제 무엇을 쓸까?&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;22&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;22,0,0&quot;&gt;단순히 데이터를 찾거나 필터링할 때&lt;/b&gt;: 무조건 &lt;b&gt;LIKE&lt;/b&gt;가 유리하다. (인덱스를 탈 수 있어서 훨씬 빠르다.)&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;22,1,0&quot;&gt;특정 패턴의 &quot;위치&quot;가 필요할 때&lt;/b&gt;: &lt;b&gt;PATINDEX&lt;/b&gt;를 쓴다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;22,2,0&quot;&gt;진짜 강력한 정규표현식(전화번호, 이메일 검증 등)을 쓰고 싶을 때&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;22,2,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSSQL 2022 이상: &lt;b&gt;REGEXP_LIKE&lt;/b&gt;를 사용한다.&lt;/li&gt;
&lt;li&gt;이전 버전: 사용자 정의 함수(UDF)를 만들거나, 프로그래밍 언어(C#, Java, Python) 단에서 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;5. REGEXP_LIKE&amp;nbsp;&lt;/b&gt;&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 data-path-to-node=&quot;1&quot;&gt;LIKE나 PATINDEX가 &quot;비슷한 패턴 찾기&quot; 수준이었다면, REGEXP_LIKE는 &quot;정교한 설계도로 정밀 타격&quot;하는 수준이라고 본다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. REGEXP_LIKE에서 쓸 수 있는 강력한 무기들&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;5&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,0,0&quot;&gt;+&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,1,0&quot;&gt;1개 이상&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,2,0&quot;&gt;[0-9]+&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,3,0&quot;&gt;숫자가 최소 하나 이상 연속됨 (1, 12, 123...)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,0,0&quot;&gt;*&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,1,0&quot;&gt;0개 이상&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,2,0&quot;&gt;AB*C&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,3,0&quot;&gt;AC, ABC, ABBC 모두 포함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,3,0,0&quot;&gt;?&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,1,0&quot;&gt;0개 또는 1개&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,2,0&quot;&gt;https?&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,3,3,0&quot;&gt;http와 https 둘 다 찾음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,4,0,0&quot;&gt;{n}&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,1,0&quot;&gt;횟수 지정&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,2,0&quot;&gt;[0-9]{3}&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,4,3,0&quot;&gt;숫자가 &lt;b data-index-in-node=&quot;4&quot; data-path-to-node=&quot;5,4,3,0&quot;&gt;정확히 3자리&lt;/b&gt;인 것만&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,5,0,0&quot;&gt;**`&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,5,1,0&quot;&gt;`**&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,5,2,0&quot;&gt;선택 (OR)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,5,3,0&quot;&gt;`(Apple&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,6,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,6,0,0&quot;&gt;^, $&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,6,1,0&quot;&gt;시작과 끝&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,6,2,0&quot;&gt;^A.*Z$&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,6,3,0&quot;&gt;A로 시작해서 Z로 끝나는 전체 문장&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 실전 비교: LIKE vs REGEXP_LIKE&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&quot;연속된 숫자 3자리로 시작하는 도시 이름&quot;을 찾는다고 가정해 보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,0,0&quot;&gt;LIKE (노가다 방식):&lt;/b&gt;(숫자가 10자리라면 [0-9]를 10번 써야 한다...)
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;WHERE CITY LIKE '[0-9][0-9][0-9]%';
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0&quot;&gt;REGEXP_LIKE (스마트한 방식):&lt;/b&gt;({3} 하나로 깔끔하게 정리된다.)
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;WHERE REGEXP_LIKE(CITY, '^[0-9]{3}');
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-path-to-node=&quot;11&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 왜 이게 &quot;진짜&quot; 정규표현식인가?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;13&quot;&gt;REGEXP_LIKE는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b data-path-to-node=&quot;12&quot; data-index-in-node=&quot;13&quot;&gt;문자열의 논리적 구조&lt;/b&gt;를 파악할 수 있기 때문이다.&lt;/li&gt;
&lt;li style=&quot;color: #333333; text-align: start;&quot; data-path-to-node=&quot;13&quot;&gt;예를 들어,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b data-path-to-node=&quot;13&quot; data-index-in-node=&quot;7&quot;&gt;이메일 형식&lt;/b&gt;을 체크할 때 LIKE로는 거의 불가능에 가깝지만, REGEXP_LIKE는 한 줄로 끝낼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjbvpX02POTAxUAAAAAHQAAAAAQsgM&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;-- 이메일 검사 (대략적인 예시)
WHERE REGEXP_LIKE(EMAIL, '^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$');
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-path-to-node=&quot;16&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-path-to-node=&quot;17&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;17,0,0&quot;&gt;버전 확인&lt;/b&gt;: 사용 중인 MSSQL이 &lt;b data-index-in-node=&quot;20&quot; data-path-to-node=&quot;17,0,0&quot;&gt;2022 버전 이전&lt;/b&gt;이라면 REGEXP_LIKE를 썼을 때 &quot;그런 함수 없는데?&quot;라는 에러가 날 수 있다. 이럴 땐 어쩔 수 없이 LIKE나 PATINDEX를 조합해서 써야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;17,1,0&quot;&gt;성능(속도)&lt;/b&gt;: 정규표현식은 매우 강력하지만, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;엔진이 복잡한 계산을 해야 하므로 단순 LIKE보다 CPU를 더 많이 쓴다.&lt;/span&gt;&lt;/b&gt; 데이터가 수천만 건이라면 꼭 필요한 곳에만 써야 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;6. 정리하기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 쌩기초: 와일드카드 (LIKE 연산자 전용)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;4&quot;&gt;가장 기본적이고 인덱스를 탈 수 있어 성능이 가장 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;5&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,1,0,0&quot;&gt;%&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,1,0&quot;&gt;무한대&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,2,0&quot;&gt;LIKE 'A%'&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,1,3,0&quot;&gt;'A'로 시작하는 모든 단어 (Apple, Ant...)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;5,2,0,0&quot;&gt;_&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,1,0&quot;&gt;한 글자&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,2,0&quot;&gt;LIKE 'A_'&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;5,2,3,0&quot;&gt;'A'로 시작하는 딱 두 글자 (At, As...)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 중급: MSSQL 기본 패턴 (LIKE &amp;amp; PATINDEX)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;8&quot;&gt;단순 와일드카드보다 조금 더 범위를 좁힐 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;9&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,1,0,0&quot;&gt;[]&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,1,1,0&quot;&gt;택일 (OR)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,1,2,0&quot;&gt;[aeiou]%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,1,3,0&quot;&gt;모음(a,e,i,o,u) 중 하나로 시작하는 것&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,2,0,0&quot;&gt;[^]&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,2,1,0&quot;&gt;부정 (NOT)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,2,2,0&quot;&gt;[^0-9]%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,2,3,0&quot;&gt;숫자로 시작하지 않는 것&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;9,3,0,0&quot;&gt;-&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,3,1,0&quot;&gt;범위&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,3,2,0&quot;&gt;[a-z]%&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;9,3,3,0&quot;&gt;소문자 a부터 z 사이로 시작하는 것&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;11&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 고급: 진짜 정규표현식 (REGEXP_LIKE)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-path-to-node=&quot;12&quot;&gt;MSSQL 2022 이상에서 사용 가능하며, 기호들을 조합해 '문법'을 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;① 위치 및 그룹 기호&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;14&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,1,0,0&quot;&gt;^&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,1,1,0&quot;&gt;시작&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,1,2,0&quot;&gt;^A : 문장의 맨 앞글자가 'A'여야 함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,2,0,0&quot;&gt;$&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,2,1,0&quot;&gt;끝&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,2,2,0&quot;&gt;Z$ : 문장의 맨 마지막 글자가 'Z'여야 함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,3,0,0&quot;&gt;**`&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,3,1,0&quot;&gt;`**&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,3,2,0&quot;&gt;선택 (OR)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;14,4,0,0&quot;&gt;.&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,4,1,0&quot;&gt;만능&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;14,4,2,0&quot;&gt;아무 문자나 딱 한 글자를 의미&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-path-to-node=&quot;15&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;② 수량자 (반복 횟수 지정) - 이게 핵심!&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;16&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;기호&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,1,0,0&quot;&gt;*&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,1,1,0&quot;&gt;0번 이상&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,1,2,0&quot;&gt;앞의 글자가 없어도 되고, 무한정 많아도 됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,2,0,0&quot;&gt;+&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,2,1,0&quot;&gt;1번 이상&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,2,2,0&quot;&gt;앞의 글자가 &lt;b data-index-in-node=&quot;7&quot; data-path-to-node=&quot;16,2,2,0&quot;&gt;최소한 한 번&lt;/b&gt;은 꼭 나와야 함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,3,0,0&quot;&gt;?&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,3,1,0&quot;&gt;0 또는 1&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,3,2,0&quot;&gt;앞의 글자가 있거나 없거나 (선택 사항)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,4,0,0&quot;&gt;{n}&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,4,1,0&quot;&gt;정확히 n번&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,4,2,0&quot;&gt;[0-9]{3} : 숫자가 딱 3자리 연속됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,5,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;16,5,0,0&quot;&gt;{n,m}&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,5,1,0&quot;&gt;n~m번 사이&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;16,5,2,0&quot;&gt;[0-9]{2,4} : 숫자가 2자리에서 4자리 사이&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;18&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 한눈에 보는 요약 (SARGability &amp;amp; Power)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-path-to-node=&quot;19&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;LIKE / PATINDEX&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;REGEXP_LIKE&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,1,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,1,0,0&quot;&gt;수준&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,1,1,0&quot;&gt;초급 ~ 중급&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,1,2,0&quot;&gt;고급 (강력함)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,2,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,2,0,0&quot;&gt;정밀도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,2,1,0&quot;&gt;대략적인 패턴 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,2,2,0&quot;&gt;매우 정교한 설계 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,3,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,3,0,0&quot;&gt;성능&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,3,1,0&quot;&gt;상대적으로 빠름 (인덱스 활용)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,3,2,0&quot;&gt;상대적으로 느림 (연산 복잡)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,4,0,0&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,4,0,0&quot;&gt;반복 지정&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,4,1,0&quot;&gt;일일이 써야 함 ([0-9][0-9])&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span data-path-to-node=&quot;19,4,2,0&quot;&gt;숫자로 지정 가능 ([0-9]{2})&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-path-to-node=&quot;21&quot; data-ke-size=&quot;size20&quot;&gt;  &lt;b&gt;실무 적용 가이드&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;22&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;22,0,0&quot;&gt;성능이 중요하다면?&lt;/b&gt; 가급적 LIKE 'A%' 처럼 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;앞부분을 고정한 와일드카드&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;22,1,0&quot;&gt;복잡한 검증(이메일, 전화번호)이 필요하다면?&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;REGEXP_LIKE&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;22,2,0&quot;&gt;특정 글자의 위치를 찾아야 한다면?&lt;/b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;PATINDEX&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL</category>
      <category>index</category>
      <category>like</category>
      <category>MSsql</category>
      <category>patindex</category>
      <category>RegExp</category>
      <category>REGEXP_LIKE</category>
      <category>SQL</category>
      <category>성능</category>
      <category>정규표현식</category>
      <category>패턴매칭</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/468</guid>
      <comments>https://sound-programming.tistory.com/468#entry468comment</comments>
      <pubDate>Fri, 17 Apr 2026 13:27:03 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 basic select Weather Observation Station 7 [성능 최적화-인덱스를 위해서]</title>
      <link>https://sound-programming.tistory.com/467</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-7/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-7/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776392696403&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;Weather Observation Station 7 | HackerRank&quot; data-og-description=&quot;Query the list of CITY names ending with vowels (a, e, i, o, u) from STATION.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-7/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-7/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/6Wibc/dJMb8ZvC8Qg/xmTlscfIllTK8nvWmUNRZk/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-7/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-7/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/6Wibc/dJMb8ZvC8Qg/xmTlscfIllTK8nvWmUNRZk/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 7 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Query the list of CITY names ending with vowels (a, e, i, o, u) from STATION.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;최적화 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT DISTINCT CITY
FROM STATION
WHERE CITY LIKE '%[aeiou]';&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;아쉬운 코드 (내코드)&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776392725803&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;select distinct city from station where right(city, 1) in ('a', 'e', 'i', 'o', 'u');&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;풀이는 간단하다 중복 제거, 뒤에 a e i o u인 도시를 찾게 조건문을 쓰면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;879&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba1g5f/dJMcafM4ZAX/eqfZ4Mnt5Ypmenv75heC31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba1g5f/dJMcafM4ZAX/eqfZ4Mnt5Ypmenv75heC31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba1g5f/dJMcafM4ZAX/eqfZ4Mnt5Ypmenv75heC31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba1g5f%2FdJMcafM4ZAX%2FeqfZ4Mnt5Ypmenv75heC31%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;892&quot; height=&quot;879&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;879&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;회사에서 수석님께 sql교육을 받았다.
&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;left right substring 등 컬럼 전체를 가공해서 where 에서 비교하는 형태는 인덱스를 타지 않는다.&lt;/li&gt;
&lt;li&gt;왜냐하면 모든 컬럼을 가공한다 = 모든 컬럼을 조회한다 라는 말이 되고 full scan이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;우리가 원하는 것은 index scan이지 full scan이 아니다 그래서 어떻게 최적화가 가능할지 gemini에 물어보니 정규표현식을 가르쳐줬다.
&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;/li&gt;
&lt;li&gt;결론은 정규표현식과 like를 사용해서 인덱스를 타자
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;left right 등을 최대한 사용하지 말자.&lt;/li&gt;
&lt;li&gt;당연히 조건문에서지 select에서 쓰는 것은 상관 없다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예를 들어 000 조건의 도시를 찾고 앞에 3글자만 보여라. 라고 했을 때&lt;/li&gt;
&lt;li&gt;이미 조건을 통해 찾은 데이터를 가공해서 보여주는 것이기 때문에 이때는 가공해도 무방하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추가로 정규표현식이나 like를 사용하더라도 앞에 %나 _가 있으면 인덱스를 타지 않는다 ㅋㅋㅋㅋ&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>HackerRank</category>
      <category>index</category>
      <category>LEFT</category>
      <category>MSsql</category>
      <category>SQL</category>
      <category>인덱스</category>
      <category>정규표현식</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/467</guid>
      <comments>https://sound-programming.tistory.com/467#entry467comment</comments>
      <pubDate>Fri, 17 Apr 2026 11:33:19 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 basic select Weather Observation Station 5 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/466</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776391570236&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;Weather Observation Station 5 | HackerRank&quot; data-og-description=&quot;Write a query to print the shortest and longest length city name along with the length of the city names.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-5/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvbicK/dJMb9gxm7ai/3mKgl2vkkDao8WvK6PQzBk/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvbicK/dJMb9gxm7ai/3mKgl2vkkDao8WvK6PQzBk/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 5 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Write a query to print the shortest and longest length city name along with the length of the city names.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.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;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET NOCOUNT ON;

SELECT TOP 1 CITY, LEN(CITY)
FROM STATION
ORDER BY LEN(CITY) ASC, CITY ASC;

SELECT TOP 1 CITY, LEN(CITY)
FROM STATION
ORDER BY LEN(CITY) DESC, CITY ASC;

go&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1776391793061&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET NOCOUNT ON;

select city, len(city) from station where len(city) = max(len(city)) or len(city) = min(len(city));
/*
Enter your query here.
Please append a semicolon &quot;;&quot; at the end of the query and enter your query in a single line to avoid error.
*/

go&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&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;/li&gt;
&lt;li&gt;도시 이름 길이가 긴 순, 짧은 순으로 정렬한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;긴 순일 경우 내림차순&lt;/li&gt;
&lt;li&gt;짧은 순일 경우 오름차순&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;정렬한 select의 가장 위에 행을 출력하면 끝&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccZUqI/dJMcaf0ytiO/kZFPobanylra1Aub8AOng1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccZUqI/dJMcaf0ytiO/kZFPobanylra1Aub8AOng1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccZUqI/dJMcaf0ytiO/kZFPobanylra1Aub8AOng1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccZUqI%2FdJMcaf0ytiO%2FkZFPobanylra1Aub8AOng1%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;831&quot; height=&quot;716&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;my sql에서 limit만 생각했는데 여기는 top으로 하면 해결된다.&lt;/li&gt;
&lt;li&gt;bottom은 없어서 정렬 후 맨 위만 뽑아야 한다.&lt;/li&gt;
&lt;li&gt;top 1도 있으니 top 2 ... n이 가능하다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/MSSQL</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>SQL</category>
      <category>Top</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/466</guid>
      <comments>https://sound-programming.tistory.com/466#entry466comment</comments>
      <pubDate>Fri, 17 Apr 2026 11:17:10 +0900</pubDate>
    </item>
    <item>
      <title>[HackerRank-MSSQL] 해커랭크 basic select Weather Observation Station 4</title>
      <link>https://sound-programming.tistory.com/465</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-4/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hackerrank.com/challenges/weather-observation-station-4/problem?isFullScreen=true&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776390748720&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;Weather Observation Station 4 | HackerRank&quot; data-og-description=&quot;Find the number of duplicate CITY names in STATION.&quot; data-og-host=&quot;www.hackerrank.com&quot; data-og-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-4/problem?isFullScreen=true&quot; data-og-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-4/problem&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bxQpK4/dJMb81fUi5g/G9hIIK98aWqlkm0acjSOz1/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229&quot;&gt;&lt;a href=&quot;https://www.hackerrank.com/challenges/weather-observation-station-4/problem?isFullScreen=true&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hackerrank.com/challenges/weather-observation-station-4/problem?isFullScreen=true&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bxQpK4/dJMb81fUi5g/G9hIIK98aWqlkm0acjSOz1/img.jpg?width=1200&amp;amp;height=640&amp;amp;face=706_91_833_229');&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;Weather Observation Station 4 | HackerRank&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Find the number of duplicate CITY names in STATION.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hackerrank.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET NOCOUNT ON;

SELECT COUNT(CITY) - COUNT(DISTINCT CITY)
FROM STATION;
/*
Enter your query here.
Please append a semicolon &quot;;&quot; at the end of the query and enter your query in a single line to avoid error.
*/

go&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&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;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2077&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N8DYx/dJMcaaSwCzy/kyTq4JCmjv0FJyQZUz9bqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N8DYx/dJMcaaSwCzy/kyTq4JCmjv0FJyQZUz9bqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N8DYx/dJMcaaSwCzy/kyTq4JCmjv0FJyQZUz9bqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN8DYx%2FdJMcaaSwCzy%2FkyTq4JCmjv0FJyQZUz9bqK%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;2077&quot; height=&quot;685&quot; data-origin-width=&quot;2077&quot; data-origin-height=&quot;685&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;select로 찾아서 distinct하고 그럴 줄 알았는데 그냥 select에서 count로 세서 뺄 줄은 몰랐다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>SQL/MSSQL</category>
      <category>HackerRank</category>
      <category>MSsql</category>
      <category>SQL</category>
      <category>해커랭크</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/465</guid>
      <comments>https://sound-programming.tistory.com/465#entry465comment</comments>
      <pubDate>Fri, 17 Apr 2026 10:55:10 +0900</pubDate>
    </item>
    <item>
      <title>[React] useEffect cleanup function (내가 한 실수 포함)</title>
      <link>https://sound-programming.tistory.com/463</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #0eb4fc;&quot;&gt;&lt;b&gt;▶▷ 서론◁◀&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;dayjs를 수정하다가 현재 페이지(컴포넌트) 외에 전역으로 영향을 미친다는 사실을 알게 되었다. 그러다보니 weekStart를 메인 페이지에서 1로 설정했고 다른 페이지에서 2로 설정했다면 충돌이 날 수밖에 없게 된다. (에러가 나지는 않지만 둘 중 하나의 방식만 선택됨) 이런 경우에 useEffect를 써서 각 컴포넌트에서만 실행되게 하고 싶었고 그 방법을 cleanup function에서 찾았다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #0eb4fc;&quot;&gt;&lt;b&gt;▶▷ 목차 ◁◀&lt;/b&gt;&lt;/span&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;/li&gt;
&lt;li&gt;언제 실행되는가&lt;/li&gt;
&lt;li&gt;자 사용하는 패턴&lt;/li&gt;
&lt;li&gt;내가 사용한 패턴&lt;/li&gt;
&lt;li&gt;주의사항&lt;/li&gt;
&lt;li&gt;정리하기&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▶&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▷ &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;1. 정의 ◁◀&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React의 useEffect에서 return하는 함수는 &lt;b&gt;cleanup function&lt;/b&gt;(정리 함수)라고 부른다.&lt;/li&gt;
&lt;li&gt;이 함수는 컴포넌트가 언마운트되거나 의존성 배열이 변경되어 effect가 다시 실행되기 전에 호출된다.&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;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▶&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▷&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;2. 언제 실행되는가 ◁◀&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;: 컴포넌트가 DOM에서 제거될 때&lt;/li&gt;
&lt;li&gt;&lt;b&gt;의존성 배열 변경 시&lt;/b&gt;: 다음 effect 실행 전에 이전 effect를 정리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컴포넌트 리렌더링 시&lt;/b&gt; (의존성이 변경된 경우)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▶&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▷&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;3. 자주 사용하는 패턴 ◁◀&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 이벤트 리스너 제거&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #383a42; text-align: left;&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const handleResize = () =&amp;gt; {
    setWindowWidth(window.innerWidth);
  };
  
  window.addEventListener('resize', handleResize);
  
  // cleanup: 이벤트 리스너 제거
  return () =&amp;gt; {
    window.removeEventListener('resize', handleResize);
  };
}, []);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 타이머 정리&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #383a42; text-align: left;&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const timer = setInterval(() =&amp;gt; {
    setCount(prev =&amp;gt; prev + 1);
  }, 1000);
  
  // cleanup: 타이머 정리
  return () =&amp;gt; {
    clearInterval(timer);
  };
}, []);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. API 요청 취소&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #383a42; text-align: left;&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const controller = new AbortController();
  
  fetch('/api/data', { signal: controller.signal })
    .then(response =&amp;gt; response.json())
    .then(data =&amp;gt; setData(data))
    .catch(err =&amp;gt; {
      if (err.name !== 'AbortError') {
        console.error(err);
      }
    });
  
  // cleanup: 진행 중인 요청 취소
  return () =&amp;gt; {
    controller.abort();
  };
}, []);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. 구독(subscription) 해제&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #383a42; text-align: left;&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const subscription = someObservable.subscribe(data =&amp;gt; {
    setData(data);
  });
  
  // cleanup: 구독 해제
  return () =&amp;gt; {
    subscription.unsubscribe();
  };
}, []);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▶&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▷&lt;span&gt; 4&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;. 내가 사용한 패턴 ◁◀&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #383a42; text-align: left;&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  // 현재 설정 백업
  const originalWeekStart = dayjs.Ls.ko?.weekStart || 1

  // 임시로 일요일 시작 설정
  dayjs.locale('ko')
  dayjs.updateLocale('ko', {
    weekStart: 0
  })

  // cleanup: 원래 설정으로 복원
  return () =&amp;gt; {
    dayjs.updateLocale('ko', {
      weekStart: originalWeekStart
    })
  }
}, [])&lt;/code&gt;&lt;/pre&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;이 패턴은 &lt;b&gt;전역 설정 임시 변경&lt;/b&gt; 패턴이다.&lt;/li&gt;
&lt;li&gt;컴포넌트가 마운트될 때 dayjs의 주간 시작일을 일요일로 변경하고, 언마운트될 때 원래 설정으로 되돌린다.&lt;/li&gt;
&lt;li&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;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▶&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▷&lt;span&gt; 5&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;. 주의사항 ◁◀&lt;/span&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;cleanup function은 &lt;b&gt;동기적&lt;/b&gt;으로 실행되어야 한다 (async 함수 사용 불가)&lt;/li&gt;
&lt;li&gt;의존성 배열이 있는 경우, 배열이 변경될 때마다 cleanup이 먼저 실행되고 새로운 effect가 실행된다&lt;/li&gt;
&lt;li&gt;cleanup을 잊으면 메모리 누수나 예상치 못한 동작이 발생할 수 있다&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;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▶&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;▷&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #a374db;&quot;&gt;6. 정리하기 ◁◀&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전역으로 설정하는 경우 스크롤이 될 수도 있고, 내가 설정한 dayjs를 사용할 수도 있다.&lt;/li&gt;
&lt;li&gt;이런 경우에 useEffect의 cleanup 함수를 사용해보자.&lt;/li&gt;
&lt;li&gt;하지만 cleanup 함수를 사용하기 전에 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;내가 사용하는 라이브러리의 함수가 전역으로 관리되는지 생각&lt;/b&gt;&lt;/span&gt;하고 개발할 필요가 있다.&amp;nbsp;&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;</description>
      <category>프론트엔드</category>
      <category>cleanup function</category>
      <category>dayjs</category>
      <category>React</category>
      <category>useEffect</category>
      <category>리액트</category>
      <category>이벤트 리스너 제거</category>
      <category>클린업</category>
      <category>클린업 함수</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/463</guid>
      <comments>https://sound-programming.tistory.com/463#entry463comment</comments>
      <pubDate>Fri, 22 Aug 2025 12:17:42 +0900</pubDate>
    </item>
    <item>
      <title>FastAPI 백엔드 개발 가이드: API 구현 순서와 모던 개발 방법론 [3탄]</title>
      <link>https://sound-programming.tistory.com/462</link>
      <description>&lt;h1&gt;6. Testing 전략&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;테스트 피라미드 구현&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 단위 테스트 (70%)&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# Repository 단위 테스트
def test_user_repository_create():
    # Given
    user_data = UserCreate(email=&quot;test@example.com&quot;, username=&quot;testuser&quot;,
password=&quot;password123&quot;)

    # When
    user = repository.create(user_data)

    # Then
    assert user.email == &quot;test@example.com&quot;
    assert user.id is not None

# Service 단위 테스트
def test_user_service_business_logic():
    # Mock 의존성을 사용한 비즈니스 로직 테스트
    pass
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 통합 테스트 (20%)&lt;/h3&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# API 엔드포인트 테스트
def test_user_creation_flow():
    # 전체 요청-응답 플로우 테스트
    pass

# 데이터베이스 연동 테스트
def test_database_operations():
    # 실제 데이터베이스와의 상호작용 테스트
    pass
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. E2E 테스트 (10%)&lt;/h3&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# 전체 사용자 시나리오 테스트
def test_complete_user_journey():
    # 사용자 등록 -&amp;gt; 로그인 -&amp;gt; 프로필 수정 -&amp;gt; 탈퇴
    pass
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 데이터 관리&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# tests/fixtures.py
import pytest
from app.domain.users.models.user import User

@pytest.fixture
def sample_user_data():
    return {
        &quot;email&quot;: &quot;test@example.com&quot;,
        &quot;username&quot;: &quot;testuser&quot;,
        &quot;password&quot;: &quot;password123&quot;
    }

@pytest.fixture
def created_user(db_session, sample_user_data):
    user = User(**sample_user_data)
    db_session.add(user)
    db_session.commit()
    return user

# 테스트에서 사용
def test_get_user(created_user):
    assert created_user.email == &quot;test@example.com&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;7. 배포 및 운영&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Docker 컨테이너화&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# Dockerfile
FROM python:3.11-slim

WORKDIR /app

# Poetry 설치
RUN pip install poetry

# 의존성 복사 및 설치
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false \\
    &amp;amp;&amp;amp; poetry install --no-dev

# 소스 코드 복사
COPY ./app ./app

# 포트 노출
EXPOSE 8000

# 실행 명령
CMD [&quot;uvicorn&quot;, &quot;app.main:app&quot;, &quot;--host&quot;, &quot;0.0.0.0&quot;, &quot;--port&quot;, &quot;8000&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - &quot;8000:8000&quot;
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
    depends_on:
      - db
      - redis

  db:
    image: postgres:13
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:alpine

volumes:
  postgres_data:
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 환경 설정&lt;/h2&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# 프로덕션용 설정
class ProductionSettings(Settings):
    debug: bool = False
    log_level: str = &quot;WARNING&quot;

    # 보안 강화
    allowed_hosts: list[str] = [&quot;yourdomain.com&quot;]

    # 성능 최적화
    database_pool_size: int = 20
    database_max_overflow: int = 30

    # 모니터링
    sentry_dsn: Optional[str] = None

    class Config:
        env_file = &quot;.env.production&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;헬스체크 및 모니터링&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# app/core/health.py
  from fastapi import APIRouter, Depends
  from sqlalchemy.orm import Session
  from app.core.database import get_db

  router = APIRouter()

  @router.get(&quot;/health&quot;)
  async def health_check():
      return {&quot;status&quot;: &quot;healthy&quot;, &quot;timestamp&quot;: datetime.utcnow()}

  @router.get(&quot;/health/db&quot;)
  async def database_health_check(db: Session = Depends(get_db)):
      try:
          # 데이터베이스 연결 확인
          db.execute(&quot;SELECT 1&quot;)
          return {&quot;status&quot;: &quot;healthy&quot;, &quot;database&quot;: &quot;connected&quot;}
      except Exception as e:
          raise HTTPException(status_code=503, detail=&quot;Database unavailable&quot;)

  @router.get(&quot;/metrics&quot;)
  async def metrics():
      # Prometheus 메트릭 반환
      return {
          &quot;active_connections&quot;: get_active_connections(),
          &quot;response_times&quot;: get_response_times(),
          &quot;error_rates&quot;: get_error_rates()
      }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;모던 백엔드 개발의 핵심 원칙&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 관심사의 분리 (Separation of Concerns)&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;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 테스트 가능한 코드 (Testable Code)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;의존성 주입으로 Mock 테스트 가능&lt;/li&gt;
&lt;li&gt;비즈니스 로직과 인프라 코드 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. API 우선 설계 (API-First Design)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OpenAPI 스펙으로 계약 우선 개발&lt;/li&gt;
&lt;li&gt;프론트엔드와 백엔드 병렬 개발 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 자동화 (Automation)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CI/CD 파이프라인으로 배포 자동화&lt;/li&gt;
&lt;li&gt;코드 품질 검사 자동화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 관찰 가능성 (Observability)&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;/li&gt;
&lt;/ul&gt;</description>
      <category>백엔드</category>
      <category>Backend</category>
      <category>docker</category>
      <category>fastapi</category>
      <category>Python</category>
      <category>Testing</category>
      <category>모던 백엔드 개발</category>
      <category>배포</category>
      <category>백엔드</category>
      <category>테스팅</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/462</guid>
      <comments>https://sound-programming.tistory.com/462#entry462comment</comments>
      <pubDate>Tue, 12 Aug 2025 17:09:14 +0900</pubDate>
    </item>
    <item>
      <title>FastAPI 백엔드 개발 가이드: API 구현 순서와 모던 개발 방법론 [2탄]</title>
      <link>https://sound-programming.tistory.com/461</link>
      <description>&lt;h1&gt;4. API 개발 순서&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 1: Pydantic Schemas 정의&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# app/domain/users/schemas/user_schemas.py
  from pydantic import BaseModel, EmailStr, Field
  from datetime import datetime
  from typing import Optional

  class UserBase(BaseModel):
      email: EmailStr
      username: str = Field(..., min_length=3, max_length=50)

  class UserCreate(UserBase):
      password: str = Field(..., min_length=8)

  class UserUpdate(BaseModel):
      email: Optional[EmailStr] = None
      username: Optional[str] = None

  class UserResponse(UserBase):
      id: int
      is_active: bool
      created_at: datetime

      class Config:
          from_attributes = True  # SQLAlchemy 모델 지원

  class UserListResponse(BaseModel):
      items: list[UserResponse]
      total: int
      page: int
      size: int
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 먼저 Schema를 정의하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계약 우선 개발: API 인터페이스를 먼저 정의&lt;/li&gt;
&lt;li&gt;타입 안전성: Pydantic이 자동으로 검증 및 직렬화&lt;/li&gt;
&lt;li&gt;문서 자동화: FastAPI가 자동으로 OpenAPI 스펙 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 2: Repository Layer 구현&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# app/domain/users/repositories/user_repository.py
  from sqlalchemy.orm import Session
  from sqlalchemy import and_, or_
  from typing import List, Optional
  from app.domain.users.models.user import User
  from app.domain.users.schemas.user_schemas import UserCreate, UserUpdate

  class UserRepository:
      def __init__(self, db: Session):
          self.db = db

      def create(self, user_data: UserCreate) -&amp;gt; User:
          &quot;&quot;&quot;사용자 생성&quot;&quot;&quot;
          db_user = User(**user_data.dict(exclude={'password'}))
          db_user.hashed_password = hash_password(user_data.password)

          self.db.add(db_user)
          self.db.commit()
          self.db.refresh(db_user)
          return db_user

      def get_by_id(self, user_id: int) -&amp;gt; Optional[User]:
          &quot;&quot;&quot;ID로 사용자 조회&quot;&quot;&quot;
          return self.db.query(User).filter(User.id == user_id).first()

      def get_by_email(self, email: str) -&amp;gt; Optional[User]:
          &quot;&quot;&quot;이메일로 사용자 조회&quot;&quot;&quot;
          return self.db.query(User).filter(User.email == email).first()

      def get_list(self, skip: int = 0, limit: int = 100) -&amp;gt; List[User]:
          &quot;&quot;&quot;사용자 목록 조회 (페이징)&quot;&quot;&quot;
          return self.db.query(User).offset(skip).limit(limit).all()

      def update(self, user_id: int, user_data: UserUpdate) -&amp;gt; Optional[User]:
          &quot;&quot;&quot;사용자 정보 업데이트&quot;&quot;&quot;
          db_user = self.get_by_id(user_id)
          if not db_user:
              return None

          update_data = user_data.dict(exclude_unset=True)
          for field, value in update_data.items():
              setattr(db_user, field, value)

          self.db.commit()
          self.db.refresh(db_user)
          return db_user

      def delete(self, user_id: int) -&amp;gt; bool:
          &quot;&quot;&quot;사용자 삭제 (소프트 삭제)&quot;&quot;&quot;
          db_user = self.get_by_id(user_id)
          if not db_user:
              return False

          db_user.is_active = False
          self.db.commit()
          return True
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Repository 패턴을 사용하는 이유&lt;/b&gt;&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;테스트 용이성: Mock Repository로 단위 테스트 가능&lt;/li&gt;
&lt;li&gt;변경 용이성: 데이터베이스 변경 시 Repository만 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 3: Service Layer 구현&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# app/domain/users/services/user_service.py
  from sqlalchemy.orm import Session
  from typing import List, Optional
  from app.domain.users.repositories.user_repository import UserRepository
  from app.domain.users.schemas.user_schemas import (
      UserCreate, UserUpdate, UserResponse, UserListResponse
  )
  from app.core.exceptions import NotFoundException, ConflictException

  class UserService:
      def __init__(self, db: Session):
          self.repository = UserRepository(db)

      def create_user(self, user_data: UserCreate) -&amp;gt; UserResponse:
          &quot;&quot;&quot;사용자 생성 비즈니스 로직&quot;&quot;&quot;
          # 비즈니스 규칙 검증
          existing_user = self.repository.get_by_email(user_data.email)
          if existing_user:
              raise ConflictException(&quot;이미 존재하는 이메일입니다.&quot;)

          # 사용자 생성
          user = self.repository.create(user_data)

          # 추가 비즈니스 로직 (이메일 발송, 로깅 등)
          self._send_welcome_email(user.email)

          return UserResponse.from_orm(user)

      def get_user(self, user_id: int) -&amp;gt; UserResponse:
          &quot;&quot;&quot;사용자 조회&quot;&quot;&quot;
          user = self.repository.get_by_id(user_id)
          if not user or not user.is_active:
              raise NotFoundException(&quot;사용자를 찾을 수 없습니다.&quot;)

          return UserResponse.from_orm(user)

      def get_users(self, page: int = 1, size: int = 20) -&amp;gt; UserListResponse:
          &quot;&quot;&quot;사용자 목록 조회&quot;&quot;&quot;
          skip = (page - 1) * size
          users = self.repository.get_list(skip=skip, limit=size)
          total = self.repository.count()

          return UserListResponse(
              items=[UserResponse.from_orm(user) for user in users],
              total=total,
              page=page,
              size=size
          )

      def update_user(self, user_id: int, user_data: UserUpdate) -&amp;gt; UserResponse:        
          &quot;&quot;&quot;사용자 정보 업데이트&quot;&quot;&quot;
          # 권한 검증 로직
          if user_data.email:
              existing_user = self.repository.get_by_email(user_data.email)
              if existing_user and existing_user.id != user_id:
                  raise ConflictException(&quot;이미 사용 중인 이메일입니다.&quot;)

          user = self.repository.update(user_id, user_data)
          if not user:
              raise NotFoundException(&quot;사용자를 찾을 수 없습니다.&quot;)

          return UserResponse.from_orm(user)

      def delete_user(self, user_id: int) -&amp;gt; bool:
          &quot;&quot;&quot;사용자 삭제&quot;&quot;&quot;
          success = self.repository.delete(user_id)
          if not success:
              raise NotFoundException(&quot;사용자를 찾을 수 없습니다.&quot;)

          return True

      def _send_welcome_email(self, email: str):
          &quot;&quot;&quot;환영 이메일 발송 (내부 메서드)&quot;&quot;&quot;
          # 이메일 발송 로직
          pass
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Service Layer의 역할:&lt;/b&gt;&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;/li&gt;
&lt;li&gt;외부 서비스 호출: 이메일, 알림 등 부가 기능&lt;/li&gt;
&lt;li&gt;검증 및 변환: 데이터 검증과 응답 형식 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 4: Controller Layer 구현&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# app/domain/users/controllers/user_controller.py
  from fastapi import APIRouter, Depends, HTTPException, Query, Path
  from sqlalchemy.orm import Session
  from typing import List

  from app.core.database import get_db
  from app.core.dependencies import get_current_user
  from app.domain.users.services.user_service import UserService
  from app.domain.users.schemas.user_schemas import (
      UserCreate, UserUpdate, UserResponse, UserListResponse
  )

  router = APIRouter(prefix=&quot;/users&quot;, tags=[&quot;users&quot;])

  @router.post(&quot;/&quot;, response_model=UserResponse, status_code=201)
  async def create_user(
      user_data: UserCreate,
      db: Session = Depends(get_db)
  ):
      &quot;&quot;&quot;
      사용자 생성

      - **email**: 유효한 이메일 주소
      - **username**: 3-50자 사용자명
      - **password**: 8자 이상 비밀번호
      &quot;&quot;&quot;
      service = UserService(db)
      return service.create_user(user_data)

  @router.get(&quot;/{user_id}&quot;, response_model=UserResponse)
  async def get_user(
      user_id: int = Path(..., gt=0, description=&quot;사용자 ID&quot;),
      db: Session = Depends(get_db),
      current_user = Depends(get_current_user)  # 인증 필요
  ):
      &quot;&quot;&quot;사용자 상세 조회&quot;&quot;&quot;
      service = UserService(db)
      return service.get_user(user_id)

  @router.get(&quot;/&quot;, response_model=UserListResponse)
  async def get_users(
      page: int = Query(1, ge=1, description=&quot;페이지 번호&quot;),
      size: int = Query(20, ge=1, le=100, description=&quot;페이지 크기&quot;),
      db: Session = Depends(get_db)
  ):
      &quot;&quot;&quot;사용자 목록 조회 (페이징)&quot;&quot;&quot;
      service = UserService(db)
      return service.get_users(page=page, size=size)

  @router.put(&quot;/{user_id}&quot;, response_model=UserResponse)
  async def update_user(
      user_id: int = Path(..., gt=0),
      user_data: UserUpdate,
      db: Session = Depends(get_db),
      current_user = Depends(get_current_user)
  ):
      &quot;&quot;&quot;사용자 정보 업데이트&quot;&quot;&quot;
      # 권한 검증: 본인 또는 관리자만 수정 가능
      if current_user.id != user_id and not current_user.is_admin:
          raise HTTPException(status_code=403, detail=&quot;권한이 없습니다.&quot;)

      service = UserService(db)
      return service.update_user(user_id, user_data)

  @router.delete(&quot;/{user_id}&quot;, status_code=204)
  async def delete_user(
      user_id: int = Path(..., gt=0),
      db: Session = Depends(get_db),
      current_user = Depends(get_current_user)
  ):
      &quot;&quot;&quot;사용자 삭제&quot;&quot;&quot;
      if current_user.id != user_id and not current_user.is_admin:
          raise HTTPException(status_code=403, detail=&quot;권한이 없습니다.&quot;)

      service = UserService(db)
      service.delete_user(user_id)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Controller Layer의 역할&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP 요청/응답 처리: 요청 파라미터 검증, 응답 직렬화&lt;/li&gt;
&lt;li&gt;라우팅: URL 경로와 HTTP 메서드 매핑&lt;/li&gt;
&lt;li&gt;인증/인가: 사용자 권한 검증&lt;/li&gt;
&lt;li&gt;예외 처리: HTTP 상태 코드와 에러 메시지 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Step 5: Exception Handling&lt;/h2&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# app/core/exceptions.py
  class BaseCustomException(Exception):
      def __init__(self, message: str):
          self.message = message
          super().__init__(self.message)

  class NotFoundException(BaseCustomException):
      pass

  class ConflictException(BaseCustomException):
      pass

  class ValidationException(BaseCustomException):
      pass

  # app/core/exception_handlers.py
  from fastapi import Request, HTTPException
  from fastapi.responses import JSONResponse

  async def not_found_exception_handler(request: Request, exc: NotFoundException):       
      return JSONResponse(
          status_code=404,
          content={&quot;error&quot;: &quot;Not Found&quot;, &quot;message&quot;: exc.message}
      )

  async def conflict_exception_handler(request: Request, exc: ConflictException):        
      return JSONResponse(
          status_code=409,
          content={&quot;error&quot;: &quot;Conflict&quot;, &quot;message&quot;: exc.message}
      )

  # main.py에서 등록
  app.add_exception_handler(NotFoundException, not_found_exception_handler)
  app.add_exception_handler(ConflictException, conflict_exception_handler)
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>백엔드</category>
      <category>API 개발 순서</category>
      <category>Backend</category>
      <category>Controller Layer</category>
      <category>fastapi</category>
      <category>Pydantic Schemas</category>
      <category>Python</category>
      <category>Repository 패턴</category>
      <category>service layer</category>
      <category>백엔드</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/461</guid>
      <comments>https://sound-programming.tistory.com/461#entry461comment</comments>
      <pubDate>Tue, 12 Aug 2025 17:07:45 +0900</pubDate>
    </item>
    <item>
      <title>FastAPI 백엔드 개발 가이드: API 구현 순서와 모던 개발 방법론 [1탄]</title>
      <link>https://sound-programming.tistory.com/460</link>
      <description>&lt;h1&gt;목차&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 개발 환경 설정&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 프로젝트 구조 설계&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. database layer 구현&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. api 개발 순서&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 모던 백엔드 개발 방법론&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. testing 전략&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. 배포 및 운영&lt;/h3&gt;
&lt;h1&gt;1. 개발 환경 설정&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;가상환경 및 의존성 관리&lt;/h2&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# Poetry 사용 (권장)
poetry init
poetry add fastapi uvicorn sqlalchemy alembic pydantic

# 또는 pip with requirements.txt
pip install fastapi uvicorn sqlalchemy alembic pydantic
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 Poetry를 사용하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;의존성 해결: pip은 의존성 충돌을 해결하지 못하지만, Poetry는 자동으로 해결&lt;/li&gt;
&lt;li&gt;락 파일: poetry.lock으로 정확한 버전 관리&lt;/li&gt;
&lt;li&gt;가상환경 통합: 자동으로 가상환경 생성 및 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 초기 설정&lt;/h2&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt; # main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI(
  title=&quot;API Documentation&quot;,
  description=&quot;RESTful API with FastAPI&quot;,
  version=&quot;1.0.0&quot;,
  docs_url=&quot;/docs&quot;,
  redoc_url=&quot;/redoc&quot;
)

# CORS 설정
app.add_middleware(
  CORSMiddleware,
  allow_origins=[&quot;*&quot;],  # 운영환경에서는 특정 도메인만 허용
  allow_credentials=True,
  allow_methods=[&quot;*&quot;],
  allow_headers=[&quot;*&quot;],
)&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;2. 프로젝트 구조 설계&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Layered Architecture (권장)&lt;/h2&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;project/
  ├── app/
  │   ├── core/                 # 핵심 설정 및 공통 기능
  │   │   ├── config.py         # 환경 변수, 설정
  │   │   ├── database.py       # DB 연결 설정
  │   │   ├── security.py       # 인증/인가
  │   │   └── exceptions.py     # 커스텀 예외
  │   ├── domain/               # 도메인별 모듈
  │   │   └── users/
  │   │       ├── controllers/  # API 엔드포인트
  │   │       ├── services/     # 비즈니스 로직
  │   │       ├── repositories/ # 데이터 액세스
  │   │       ├── schemas/      # Pydantic 모델
  │   │       └── models/       # SQLAlchemy 모델
  │   ├── shared/               # 공통 유틸리티
  │   │   ├── utils.py
  │   │   └── constants.py
  │   └── main.py
  ├── tests/
  ├── migrations/               # Alembic 마이그레이션
  ├── docker-compose.yml
  ├── Dockerfile
  └── pyproject.toml           # Poetry 설정
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 이런 구조를 사용하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Domain-Driven Design (DDD) 접근
&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;의존성 역전: Repository 패턴으로 데이터베이스 의존성 분리&lt;/li&gt;
&lt;li&gt;테스트 용이성: 각 레이어를 독립적으로 테스트 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Layered Architecture 이유&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Controller Layer: HTTP 요청/응답 처리만 담당&lt;/li&gt;
&lt;li&gt;Service Layer: 비즈니스 로직 집중, 트랜잭션 관리&lt;/li&gt;
&lt;li&gt;Repository Layer: 데이터 액세스 추상화&lt;/li&gt;
&lt;li&gt;Model Layer: 데이터 구조 정의&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;3. Database Layer 구현&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Database 설정&lt;/h2&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# app/core/database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

DATABASE_URL = &quot;sqlite:///./app.db&quot;

engine = create_engine(
  DATABASE_URL,
  poolclass=StaticPool,  # SQLite용
  connect_args={&quot;check_same_thread&quot;: False}
)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

def get_db():
  &quot;&quot;&quot;의존성 주입용 DB 세션&quot;&quot;&quot;
  db = SessionLocal()
  try:
      yield db
  finally:
      db.close()&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. SQLAlchemy Models&lt;/h2&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# app/domain/users/models/user.py
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from sqlalchemy.sql import func
from app.core.database import Base

class User(Base):
  __tablename__ = &quot;users&quot;

  id = Column(Integer, primary_key=True, index=True)
  email = Column(String, unique=True, index=True, nullable=False)
  username = Column(String, unique=True, index=True, nullable=False)
  hashed_password = Column(String, nullable=False)
  is_active = Column(Boolean, default=True)
  created_at = Column(DateTime(timezone=True), server_default=func.now())
  updated_at = Column(DateTime(timezone=True), onupdate=func.now())&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Alembic 마이그레이션 설정&lt;/h2&gt;
&lt;pre class=&quot;shell&quot; data-ke-language=&quot;shell&quot;&gt;&lt;code&gt;# 초기 설정
alembic init migrations

# 마이그레이션 파일 생성
alembic revision --autogenerate -m &quot;Create users table&quot;

# 마이그레이션 실행
alembic upgrade head&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 Alembic을 사용하는가?&lt;/b&gt;&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;/li&gt;
&lt;li&gt;배포 안전성: 운영 환경에서 안전한 스키마 업데이트&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>백엔드</category>
      <category>alembic</category>
      <category>Backend</category>
      <category>ddd</category>
      <category>fastapi</category>
      <category>Layered Architecture</category>
      <category>poetry</category>
      <category>Python</category>
      <category>SQL</category>
      <category>백엔드</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/460</guid>
      <comments>https://sound-programming.tistory.com/460#entry460comment</comments>
      <pubDate>Tue, 12 Aug 2025 17:00:41 +0900</pubDate>
    </item>
    <item>
      <title>[인공지능] Claude Code VS Cursor AI</title>
      <link>https://sound-programming.tistory.com/459</link>
      <description>&lt;h1&gt;&lt;b&gt;커서(Cursor)&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커서는 AI를 활용한 코드 작성 및 편집 도구로, 개발자가 코드를 빠르게 작성하고 수정할 수 있도록 지원한다. 특히 반복 작업의 자동화와 다양한 AI 모델의 통합이 강점이다.&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. Tab 기능&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;: 탭(Tab) 키를 활용해 반복적인 코딩 작업을 빠르게 수행 가능. 예를 들어, 비슷한 패턴의 코드를 여러 번 작성해야 할 때, 탭 키로 자동 완성 및 생성을 지원.&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 여러 모델 사용 가능&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커서는 다양한 AI 모델을 통합적으로 사용 가능:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Claude&lt;/b&gt;: Anthropic의 모델로, 코드 생성 및 자연어 처리에 강점.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GPT&lt;/b&gt;: OpenAI의 모델로, 범용적인 코드 작성 및 문제 해결에 유용.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Gemini&lt;/b&gt;: Google의 모델로, 특정 작업에 최적화된 성능 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 사용자는 작업의 성격에 따라 적합한 모델을 선택하거나, 여러 모델을 조합해 문제를 해결 가능. 예를 들어, Claude로 코드 구조를 잡고, GPT로 세부 로직을 작성.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점&lt;/b&gt;: 모델 간 전환 시 일관성 문제가 발생할 가능성 있음(예: 코드 스타일 차이).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;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;b&gt;수정 단위별 Accept 버튼&lt;/b&gt;: 코드 수정 시 변경된 부분마다 Accept 버튼이 제공되어, 사용자가 원하는 수정만 선택적으로 적용 가능.&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 세밀한 코드 제어가 가능하며, 대규모 수정 시 실수를 줄이는 데 효과적.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;단점&lt;/h2&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;h1&gt;&lt;b&gt;클로드(Claude) 코드&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클로드는 Anthropic에서 개발한 AI 모델로, 코드 생성 및 수정에 특화된 기능을 제공한다. 특히 Sonnet 4.0과 Opus 모델을 활용해 꼼꼼하고 정밀한 코드 작업을 지원한다. 제공된 정보에 따르면, 클로드는 특정 구독 플랜(Pro, Max)에 따라 사용량과 기능이 달라진다.&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. claude sonnet 4.0&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;: Sonnet 4.0이 디폴트로 설정되어 있어, 별도 설정 없이 고성능 코드 생성 및 수정 가능.&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 별도 설정 없이 바로 사용 가능하며, 안정적인 성능을 보장.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. claude opus&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;: Max 구독 플랜에서 사용 가능. 대규모 코드 수정이나 복잡한 프로젝트에 최적화.&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;예: 레거시 코드 리팩토링, 복잡한 DOM 구조 수정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 대규모 작업에서 시간 절약 가능. 특히 복잡한 구조의 코드를 한 번에 처리할 때 유리.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. ToDo&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; ToDo 리스트를 기반으로 문제를 체계적으로 분석하고 해결.
&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;: 제공된 코드 블록에서 DOM nesting 에러를 단계적으로 해결.
&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;: Typography 컴포넌트의 &amp;lt;p&amp;gt; 태그 내 &amp;lt;div&amp;gt; 중첩 문제 발견.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;해결 과정&lt;/b&gt;:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ToDo 리스트 작성(문제 찾기, 수정, 테스트).&lt;/li&gt;
&lt;li&gt;코드 분석(165번째 줄의 문제 확인).&lt;/li&gt;
&lt;li&gt;수정 제안(Typography를 Box로 변경, 색상 및 스타일 조정).&lt;/li&gt;
&lt;li&gt;ToDo 업데이트 및 완료 보고.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결과&lt;/b&gt;: 올바른 DOM 구조로 수정 완료, 에러 해결.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;코드 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1754882722932&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;● 이 에러는 HTML DOM 구조 규칙 위반 때문입니다. &amp;lt;p&amp;gt; 태그 안에 &amp;lt;div&amp;gt; 태그가 들어가면       
  안 되는데, Typography 컴포넌트가 기본적으로 &amp;lt;p&amp;gt; 태그를 렌더링하고 그 안에 Grid나        
  div가 포함되어 있어서 발생합니다.

● Update Todos
  ⎿  ☐ Find the DOM nesting issue in onedb page components
     ☐ Fix Typography component with nested div elements
     ☐ Test the fix

● 에러 스택을 보면 TopListBox 컴포넌트에서 문제가 발생하고 있습니다. 이 컴포넌트를        
  확인해보겠습니다:

● Read(src\views\components\box\top-list-box.tsx)
  ⎿  Read 216 lines (ctrl+r to expand)

● 문제를 찾았습니다! 165번째 줄에서 Typography 컴포넌트 안에 Link가 있고, 그 Link
  안에 다시 Stack과 Typography가 중첩되어 있습니다. Typography는 기본적으로 &amp;lt;p&amp;gt;
  태그로 렌더링되는데, 그 안에 &amp;lt;div&amp;gt; (Stack)가 들어가면 DOM 규칙 위반입니다.

● Update Todos
  ⎿  ☒ Find the DOM nesting issue in onedb page components
     ☐ Fix Typography component with nested div elements
     ☐ Test the fix

● 이제 이 문제를 수정하겠습니다. Typography를 Box나 div로 바꾸거나, component prop을      
   사용해서 올바른 HTML 태그로 렌더링하도록 수정하겠습니다:

● Update(src\views\components\box\top-list-box.tsx)
  ⎿  Updated src\views\components\box\top-list-box.tsx with 4 additions and 3
     removals
       162                          textAlign={'start'}
       163                        &amp;gt;{`${data.category.categoryName} &amp;gt;
             ${data.category.child.categoryName}`}&amp;lt;/Typography&amp;gt;
       164                        {sessionTypeChip(data)}
       165 -                      &amp;lt;Typography variant='body2' color={'primary'} 
     textAlign={'start'} sx={{ cursor: 'pointer' }}&amp;gt;
           - textAlign={'start'} sx={{ cursor: 'pointer' }}&amp;gt;
       165 +                      &amp;lt;Box sx={{ cursor: 'pointer' }}&amp;gt;
       166                          &amp;lt;Link
       167                            onClick={event =&amp;gt; {
       168                              event.preventDefault()
       169
     router.push(`/onedb/content/${data.onedbId}`)
       170                            }}
       171 +                          color={'primary'}
       172                          &amp;gt;
       173                            &amp;lt;Stack direction={'row'} spacing={2}
             alignItems={'center'}&amp;gt;
       174 -                            &amp;lt;Typography variant={'Body2'} 
     fontWeight={600} textAlign={'start'}&amp;gt;
           - fontWeight={600} textAlign={'start'}&amp;gt;
       174 +                            &amp;lt;Typography variant={'Body2'} 
     fontWeight={600} textAlign={'start'} color={'primary'}&amp;gt;
           + fontWeight={600} textAlign={'start'} color={'primary'}&amp;gt;
       175                                {data.subject}
       176                              &amp;lt;/Typography&amp;gt;
       177                              {data.hasAttachments &amp;amp;&amp;amp; &amp;lt;Icon
             icon={'fa:paperclip'} style={{ flexShrink: 0 }}&amp;gt;&amp;lt;/Icon&amp;gt;}
     ...
       184                              )}
       185                            &amp;lt;/Stack&amp;gt;
       186                          &amp;lt;/Link&amp;gt;
       187 -                      &amp;lt;/Typography&amp;gt;
       187 +                      &amp;lt;/Box&amp;gt;
       188                      &amp;lt;/Stack&amp;gt;
       189
       190                      &amp;lt;Typography variant={'body2'} minWidth={'80px'}&amp;gt;

● Update Todos
  ⎿  ☒ Find the DOM nesting issue in onedb page components
     ☒ Fix Typography component with nested div elements
     ☒ Test the fix

● 완료! DOM nesting 에러를 수정했습니다.

  문제:
  - Typography 컴포넌트(기본적으로 &amp;lt;p&amp;gt; 태그로 렌더링)
  - 그 안에 Link 컴포넌트가 있고
  - Link 안에 다시 Stack(div) 컴포넌트가 중첩되어 있음
  - HTML 규칙상 &amp;lt;p&amp;gt; 안에 &amp;lt;div&amp;gt;가 올 수 없음

  해결:
  - Typography를 Box로 변경 (&amp;lt;div&amp;gt;로 렌더링됨)
  - 텍스트 색상을 Link에 직접 적용
  - Typography 내부의 텍스트 색상을 명시적으로 설정

  변경 사항:
  // 이전 (잘못된 DOM 구조)
  &amp;lt;Typography variant='body2' color={'primary'}&amp;gt;
    &amp;lt;Link&amp;gt;
      &amp;lt;Stack&amp;gt;...&amp;lt;/Stack&amp;gt; // ❌ p &amp;gt; a &amp;gt; div 구조
    &amp;lt;/Link&amp;gt;
  &amp;lt;/Typography&amp;gt;

  // 수정 후 (올바른 DOM 구조)
  &amp;lt;Box sx={{ cursor: 'pointer' }}&amp;gt;
    &amp;lt;Link color={'primary'}&amp;gt;
      &amp;lt;Stack&amp;gt;...&amp;lt;/Stack&amp;gt; // ✅ div &amp;gt; a &amp;gt; div 구조
    &amp;lt;/Link&amp;gt;
  &amp;lt;/Box&amp;gt;

  이제 onedb 페이지에서 DOM nesting 경고가 더 이상 나타나지 않을 것입니다!&lt;/code&gt;&lt;/pre&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;&lt;b&gt;중간 저장 및 수정&lt;/b&gt;: 작업 중 Esc 키를 눌러 ToDo를 일시 중지하고, 필요한 부분만 수정 후 재개 가능.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장점&lt;/b&gt;: 체계적이고 투명한 워크플로우 제공. 복잡한 디버깅 시 작업 추적이 용이.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 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;&lt;b&gt;Pro 플랜:&lt;/b&gt; Sonnet 4: 40 ~ 80시간&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Max X5 플랜:&lt;/b&gt; Sonnet 4: 140 ~ 280시간, Opus: 15 ~ 35시간&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Max X20 플랜:&lt;/b&gt; Sonnet 4: 800 ~ 1,600 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;b&gt;소넷 모델 기준 월 사용량 비교&lt;/b&gt;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커서 (Cursor) - Sonnet 4 기준&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Pro&lt;/b&gt; ($20/월): &lt;b&gt;월 225회&lt;/b&gt; 요청&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Pro+&lt;/b&gt; ($60/월): &lt;b&gt;월 675회&lt;/b&gt; 요청&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ultra&lt;/b&gt; ($200/월): &lt;b&gt;월 4,500회&lt;/b&gt; 요청&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클로드 (Claude) - 5시간마다 리셋 기준&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;월 사용량 계산 (30일 기준: 144번의 5시간 주기)&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;Pro&lt;/b&gt; ($20/월): &lt;b&gt;월 6,480회&lt;/b&gt; 메시지
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5시간마다 45개 &amp;times; 144주기 = 6,480개&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Max 확장&lt;/b&gt; ($100/월): &lt;b&gt;월 32,400회&lt;/b&gt; 메시지
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5시간마다 225개 &amp;times; 144주기 = 32,400개&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Max 최대&lt;/b&gt; ($200/월): &lt;b&gt;월 129,600회&lt;/b&gt; 메시지
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5시간마다 900개 &amp;times; 144주기 = 129,600개&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 $20 가격대에서:&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;커서 Pro&lt;/b&gt;: 월 225회&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클로드 Pro&lt;/b&gt;: 월 6,480회&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 품질 측면에서의 우위&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 시점(2025년 8월)에서 코드 개발에 있어 Claude Sonnet과 Opus를 능가하는 AI 모델은 없다고 단언할 수 있다. 특히 복잡한 로직 구현과 코드 구조 설계에서 보여주는 Claude의 성능은 압도적이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;비용 효율성의 명확한 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황에서 자연스럽게 &quot;어떤 플랫폼이 우수한 모델을 더 경제적으로 사용할 수 있게 해주는가?&quot;라는 질문이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;같은 $20 투자 기준:&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;Cursor Pro&lt;/b&gt;: 월 225회 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Claude Pro&lt;/b&gt;: 월 6,480회 사용 (약 29배 차이)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 단순히 숫자상의 차이가 아니다. 실제 개발 과정에서 반복적인 질문과 수정이 필요한 상황을 고려하면, Claude의 압도적인 사용량은 개발 속도와 직결된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;일관성과 품질에 대한 기대&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude의 또 다른 강점은 &lt;b&gt;모델의 일관성&lt;/b&gt;이다. Cursor의 경우 여러 모델(Claude, GPT, Gemini)을 자동으로 전환하는 시스템이지만, 이로 인해 코드 스타일이나 접근 방식에서 일관성이 떨어질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Claude는 Sonnet과 Opus라는 검증된 모델만을 사용하기 때문에, 프로젝트 전반에 걸쳐 &lt;b&gt;일관된 코드 품질과 스타일&lt;/b&gt;을 유지할 수 있다.&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;3개월간의 Cursor 사용&lt;/b&gt;과 &lt;b&gt;1개월간의 Claude 사용&lt;/b&gt; 경험을 비교해본 결과, 터미널 기반의 Claude 환경이 다소 불편함에도 불구하고 다음과 같은 이유로 Cursor 구독을 취소하게 되었다:&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Claude의 장점&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; (29배 많은 사용량)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;일관된 고품질 모델&lt;/b&gt; 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;체계적인 문제 해결 접근법&lt;/b&gt; (ToDo 시스템)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정확한 코드 분석과 수정 제안&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;생산성과 비용 효율성의 균형&lt;/b&gt;이 가장 중요하다. 터미널 환경의 불편함은 적응으로 극복할 수 있지만, 비용 대비 성능의 차이는 장기적으로 더 큰 영향을 미친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 개인 개발자나 스타트업처럼 예산에 민감한 환경에서는 Claude의 선택이 거의 필수적이라고 생각한다. &lt;b&gt;같은 예산으로 29배 많은 AI 어시스턴스&lt;/b&gt;를 받을 수 있다는 것은, 곧 더 많은 실험과 더 빠른 개발 사이클을 의미한다.&lt;/p&gt;</description>
      <category>인공지능</category>
      <category>claude code</category>
      <category>claude opus</category>
      <category>claude sonnet</category>
      <category>cursor ai</category>
      <category>장단점</category>
      <category>커서</category>
      <category>코딩어시스턴트</category>
      <category>클로드 소넷</category>
      <category>클로드 오푸스</category>
      <category>클로드 코드</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/459</guid>
      <comments>https://sound-programming.tistory.com/459#entry459comment</comments>
      <pubDate>Mon, 11 Aug 2025 12:40:28 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 [Lv. 2] 완전범죄 {언어 : JavaScript}</title>
      <link>https://sound-programming.tistory.com/457</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/389480#&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/389480#&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1745741817738&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/389480#&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhW30e/hyYIha1vCY/V0Ir7tPQrZkEgoCKGPvugk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/DNoI5/hyYL2Rc7dN/DfV1dqFaFyTUtKicDsU2n1/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/389480#&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/389480#&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhW30e/hyYIha1vCY/V0Ir7tPQrZkEgoCKGPvugk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/DNoI5/hyYL2Rc7dN/DfV1dqFaFyTUtKicDsU2n1/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(info, n, m) {
    let answer = 0;
    const lenI = info.length;
    info.sort(([a, b], [c, d]) =&amp;gt; c/d - a/b);
    let [cntA, cntB] = [0, 0];
    for (let i = 0; i &amp;lt; lenI; i++) {
        const [showA, showB] = info.at(i);
        if (cntB + showB &amp;lt; m) {
            cntB += showB;
        } else {
            cntA += showA;
        }
    }
    if (cntA &amp;gt;= n) {
        answer = -1;
    } else {
        answer = cntA;
    }
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;A에게 부담이 되는 흔적부터 정렬한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;여기서 A에게 부담이 되는 흔적이란 무작정 흔적의 개수가 많은 것을 의미하지 않는다.&lt;/li&gt;
&lt;li&gt;예를 들어 [2, 3]과 [1, 1]이 있다면 A에게 부담이 되는 것은 [1, 1]이 된다.&lt;/li&gt;
&lt;li&gt;왜냐하면 B가 3의 흔적을 남기면 A의 흔적 2개를 지우는 것이지만&lt;/li&gt;
&lt;li&gt;B가 [1, 1]씩 3번 흔적을 남기면 A의 흔적 3개를 지울 수 있다.&lt;/li&gt;
&lt;li&gt;따라서 [a흔적, b흔적] 을 a흔적을 b흔적으로 나눈 값이 큰 순으로 정렬한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;정렬된 값을 B의 최대 수용량만큼 채운다.&lt;/li&gt;
&lt;li&gt;나머지는 A에 채운다.&lt;/li&gt;
&lt;li&gt;A가 n 이상이면 answer = -1&lt;/li&gt;
&lt;li&gt;아니라면 A의 흔적만큼 반환하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXPhIe/btsNBMfombA/mvcIFHTDDinukAaEymnTw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXPhIe/btsNBMfombA/mvcIFHTDDinukAaEymnTw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXPhIe/btsNBMfombA/mvcIFHTDDinukAaEymnTw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXPhIe%2FbtsNBMfombA%2FmvcIFHTDDinukAaEymnTw0%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;471&quot; height=&quot;488&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;처음엔 마냥 A에게 많은 흔적이 되는 것 부터 지웠다.&lt;/li&gt;
&lt;li&gt;오랜만에 프로그래머스 lv2문제들이 올라와서 남김없이 풀어보려고 한다.&lt;/li&gt;
&lt;li&gt;시간복잡도를 계산하지 않았다면 이걸 dfs로 풀었을 것 같다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;dfs로 접근하게 된다면 흔적을 남길지 지울지 하는 선택지 2개&lt;/li&gt;
&lt;li&gt;총 info의 길이 40개&lt;/li&gt;
&lt;li&gt;2^40 = 1,099,511,627,776&lt;/li&gt;
&lt;li&gt;이렇게 되면 시간초과를 해결할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>2025 프로그래머스 코드챌린지 2차 예선</category>
      <category>greedy</category>
      <category>javascript</category>
      <category>Lv. 2</category>
      <category>programmers</category>
      <category>그리디</category>
      <category>완전범죄</category>
      <category>자바스크립트</category>
      <category>정렬</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/457</guid>
      <comments>https://sound-programming.tistory.com/457#entry457comment</comments>
      <pubDate>Sun, 27 Apr 2025 17:24:18 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 [Lv. 2] 지게차와 크레인 {언어 : JavaScript}</title>
      <link>https://sound-programming.tistory.com/456</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/388353&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/388353&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1742707575855&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/388353&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/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/388353&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/388353&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(storage, requests) {
    let cnt = 0;
    
    const n = storage.length;
    const m = storage.at(0).length;
    const di = [-1, 1, 0, 0];
    const dj = [0, 0, -1, 1];
    const isValid = (ni, nj) =&amp;gt; {
        return 0 &amp;lt;= ni &amp;amp;&amp;amp; ni &amp;lt; n+2 &amp;amp;&amp;amp; 0 &amp;lt;= nj &amp;amp;&amp;amp; nj &amp;lt; m+2;
    }
    
    const board = Array.from({length: n+2}, () =&amp;gt; Array(m+2).fill(0));
    for (let i = 1; i &amp;lt; n+1; i++) {
        for (let j = 1; j &amp;lt; m+1; j++) {
            const ascii = storage.at(i-1).at(j-1).charCodeAt();
            board[i][j] = ascii - 64;
        }
    }
    
    requests.forEach((e) =&amp;gt; {
        const lenE = e.length;
        const selected = e.at(0).charCodeAt() - 64;
        if (lenE === 2) {
            for (let i = 1; i &amp;lt; n+2; i++) {
                for (let j = 1; j &amp;lt; m+2; j++) {
                    if (board.at(i).at(j) === selected) {
                        board[i][j] = -1;
                        cnt++;
                    }
                }
            }
        } else {
            const stack = [];
            // -1이 있는 부분 중에 0이랑 닿는 부분 0으로 만들기
            const visited = Array.from({length: n+2}, () =&amp;gt; Array(m+2).fill(0));
            const queue = [[0, 0]];
            while (queue.length &amp;gt; 0) {
                const [i, j] = queue.shift();
                for (let d = 0; d &amp;lt; 4; d++) {
                    const ni = i + di[d];
                    const nj = j + dj[d];
                    if (isValid(ni, nj) &amp;amp;&amp;amp; visited.at(ni).at(nj) === 0) {
                        const banianj = board.at(ni).at(nj);
                        if (banianj === 0) {
                            queue.push([ni, nj]);
                            visited[ni][nj] = 1;
                        } else if (banianj === -1) {
                            queue.push([ni, nj]);
                            visited[ni][nj] = 1;
                            board[ni][nj] = 0;
                        }
                    }
                }
            }
            // 0이랑 닿는 부분 stack에 넣기
            for (let i = 1; i &amp;lt; n+2; i++) {
                for (let j = 1; j &amp;lt; m+2; j++) {
                    const baiaj = board.at(i).at(j);
                    if (baiaj === selected) {
                        for (let d = 0; d &amp;lt; 4; d++) {
                            const ni = i + di[d];
                            const nj = j + dj[d];
                            if (isValid(ni, nj) &amp;amp;&amp;amp; board.at(ni).at(nj) === 0) {
                                stack.push([i, j])
                                break;
                            }
                        }
                    }
                }
            }
            cnt += stack.length;
            stack.forEach(([i, j]) =&amp;gt; {
                board[i][j] = 0;
            })
        }
    })
    const answer = n * m - cnt;
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스토리지를 0으로 감싸서 더 큰 배열을 만든다.
&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;/li&gt;
&lt;li&gt;0과 닿는 부분을 지우고 0으로 만든다.&lt;/li&gt;
&lt;li&gt;모두 지울 수 있는 경우 -1로 만들고 0과 닿았는지 확인하여 -1이 0과 닿았으면 0으로 바꿔준다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-1이 바깥이 된 경우 언제까지나 -1로 있을 수는 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이런식으로 계산해서 남는 부분의 개수를 출력하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p9ay1/btsMUroXy8D/MxxZKWrir7HOqLfSh6Ss71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p9ay1/btsMUroXy8D/MxxZKWrir7HOqLfSh6Ss71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p9ay1/btsMUroXy8D/MxxZKWrir7HOqLfSh6Ss71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp9ay1%2FbtsMUroXy8D%2FMxxZKWrir7HOqLfSh6Ss71%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;472&quot; height=&quot;375&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오랜만에 풀면 array 설정 방법도 헷갈린다.&lt;/li&gt;
&lt;li&gt;bfs로 푸는 방법을 떠올렸으나 크레인으로 뺀 부분을 어떻게 처리 해야할지 고민했었다.&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>ASCII</category>
      <category>bfs</category>
      <category>javascript</category>
      <category>Lv. 2</category>
      <category>programmers</category>
      <category>너비 우선 탐색</category>
      <category>아스키코드</category>
      <category>자바스크립트</category>
      <category>지게차와 크레인</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/456</guid>
      <comments>https://sound-programming.tistory.com/456#entry456comment</comments>
      <pubDate>Sun, 23 Mar 2025 14:32:40 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 [Lv. 2] 비밀 코드 해독 {언어 : JavaScript}</title>
      <link>https://sound-programming.tistory.com/455</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/388352&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/388352&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1742707096539&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/388352&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/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/388352&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/388352&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/btcQkL/hyYr3ku5xT/b6YcskJKWvHeuCqbCEf101/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(n, q, ans) {
    const lenQ = q.length;
    let answer = 0;
    for (let i = 1; i &amp;lt;= n; i++) {
        for (let j = i+1; j &amp;lt;= n; j++) {
            for (let k = j+1; k &amp;lt;= n; k++) {
                for (let l = k+1; l &amp;lt;= n; l++) {
                    for (let m = l+1; m &amp;lt;= n; m++) {
                        // 현재 배열이 q와 비교했을 때 ans 값과 일치하는지 확인
                        let selectedArr = [i, j, k, l, m];
                        let check = true;
                        for (let o = 0; o &amp;lt; lenQ; o++) {
                            let cnt = 0;
                            for (let p = 0; p &amp;lt; 5; p++) {
                                if (q.at(o).includes(selectedArr.at(p))) {
                                    cnt++;
                                }
                            }
                            if (cnt !== ans.at(o)) {
                                check = false;
                                break;
                            }
                        }
                        if (check) {
                            answer++;
                        }
                    }
                }
            }
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;dfs로 만들다가 실패해서 5중 for문으로 만들었다.&lt;/li&gt;
&lt;li&gt;조합을 만들어서 q의 요소들과 비교한다.&lt;/li&gt;
&lt;li&gt;ans와 같은 값이 나오면 answer++&lt;/li&gt;
&lt;li&gt;이후 answer를 출력하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmnqz2/btsMTfiJ6ho/7in2HwhhZFsUkkK3k0BIZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmnqz2/btsMTfiJ6ho/7in2HwhhZFsUkkK3k0BIZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmnqz2/btsMTfiJ6ho/7in2HwhhZFsUkkK3k0BIZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcmnqz2%2FbtsMTfiJ6ho%2F7in2HwhhZFsUkkK3k0BIZK%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;461&quot; height=&quot;452&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사실 dfs를 사용해야 더 깔끔한 풀이가 될 수 있지만 결국 가장 직관적이고 바로 해결할 수 있는 방법을 고안했다.&lt;/li&gt;
&lt;li&gt;어차피 조합은 반복문의 연속이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>dfs</category>
      <category>javascript</category>
      <category>Lv. 2</category>
      <category>programmers</category>
      <category>반복문</category>
      <category>비밀 코드 해독</category>
      <category>자바스크립트</category>
      <category>조합</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/455</guid>
      <comments>https://sound-programming.tistory.com/455#entry455comment</comments>
      <pubDate>Sun, 23 Mar 2025 14:23:13 +0900</pubDate>
    </item>
    <item>
      <title>줄 바꿈 CRLF, LF 문제 해결</title>
      <link>https://sound-programming.tistory.com/454</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;정의&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CRLF
&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;\r\n&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LF
&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;\n&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 상황&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.editorconfig와 개발 툴을 사용해서 CRLF를 LF로 바꿔야 한다.&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;WebStorm과 달리 VS Code에서는 &lt;span&gt;.editorconfig&lt;/span&gt;를 기본적으로 사용하지 않는다.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;CRLF를 LF로 바꾸고 싶으나 코드를 최소한으로 수정해서(개발 툴을 사용해서) 원하는 결과를 얻고 싶다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목표&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;파일 하나만 CRLF 에서 LF로 바꾸기&lt;/li&gt;
&lt;li&gt;VS Code 설정으로 줄 끝 문자 변경하&lt;/li&gt;
&lt;li&gt;확장 프로그램 사용하기&lt;/li&gt;
&lt;li&gt;Git 설정으로 CRLF 방지하기&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 파일 하나만 CRLF에서 LF로 바꾸기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단계:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;변환하고 싶은 파일을 VS Code에서 연다.&lt;/li&gt;
&lt;li&gt;오른쪽 하단에 현재 줄 끝 문자가 표시된다 (예: CRLF 또는 LF).&lt;/li&gt;
&lt;li&gt;CRLF을 클릭하면 LF로 변경할 수 있는 옵션이 나타난다. LF를 선택.&lt;/li&gt;
&lt;li&gt;파일을 저장(Ctrl + S)하면 LF로 변환된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDwmd9/btsMQpkIaeB/Ndjku58dgZDzYIB7q2Pf6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDwmd9/btsMQpkIaeB/Ndjku58dgZDzYIB7q2Pf6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDwmd9/btsMQpkIaeB/Ndjku58dgZDzYIB7q2Pf6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDwmd9%2FbtsMQpkIaeB%2FNdjku58dgZDzYIB7q2Pf6k%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;1228&quot; height=&quot;99&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. VS Code 설정으로 줄 끝 문자 변경하&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;&lt;b&gt;단계:&lt;/b&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;VS Code를 열고 왼쪽 하단의 톱니바퀴 아이콘(설정)을 클릭하거나 &lt;span&gt;Ctrl + ,&lt;/span&gt; (Windows) / &lt;span&gt;Cmd + ,&lt;/span&gt; (Mac)를 누른다.&lt;/li&gt;
&lt;li&gt;검색창에 &lt;span&gt;Files: Eol&lt;/span&gt;을 입력한다.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Files: Eol&lt;/span&gt; 설정에서 기본값(&lt;span&gt;\r\n&lt;/span&gt;, CRLF)을 &lt;span&gt;\n&lt;/span&gt; (LF)으로 변경한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;효과:&lt;/b&gt; 이후 저장하는 모든 파일이 LF로 저장된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;따라서 yarn format 등을 사용해서 저장하면 모든 파일이 자동으로 LF로 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1660&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR1Sqv/btsMQ4Ao98z/Hpir2dLObdJM2MkNdaEnuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR1Sqv/btsMQ4Ao98z/Hpir2dLObdJM2MkNdaEnuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR1Sqv/btsMQ4Ao98z/Hpir2dLObdJM2MkNdaEnuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR1Sqv%2FbtsMQ4Ao98z%2FHpir2dLObdJM2MkNdaEnuK%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;1660&quot; height=&quot;542&quot; data-origin-width=&quot;1660&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.&amp;nbsp;확장 프로그램 사용하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EditorConfig for VS Code 확장 프로그램을 설치한다.&lt;/li&gt;
&lt;li&gt;.editorconfig 파일을 만든다. (현재는 이미 만들어져 있음)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742438699835&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root = true
[*]
end_of_line = lf&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4. Git 설정으로 CRLF 방지하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.gitattributes 파일을 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742438789747&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;* text=auto eol=lf&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Git 설정 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1742438877859&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global core.autocrlf false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트(팀, 개인)</category>
      <category>CRLF</category>
      <category>EditorConfig</category>
      <category>editorconfig for vs code</category>
      <category>end of line</category>
      <category>EOL</category>
      <category>git</category>
      <category>gitattributes</category>
      <category>LF</category>
      <category>vscode</category>
      <category>Webstorm</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/454</guid>
      <comments>https://sound-programming.tistory.com/454#entry454comment</comments>
      <pubDate>Thu, 20 Mar 2025 11:49:00 +0900</pubDate>
    </item>
    <item>
      <title>GIT 사용법 정리 (2025-03-18)</title>
      <link>https://sound-programming.tistory.com/453</link>
      <description>&lt;h2 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. 브랜치 관리&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;브랜치 생성 및 전환&lt;/span&gt;&lt;/h3&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;git branch &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 새로운 브랜치 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git checkout &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 해당 브랜치로 이동 (구버전)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git switch &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 해당 브랜치로 이동 (권장)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git switch -c &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 브랜치 생성과 동시에 전환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;브랜치 삭제&lt;/span&gt;&lt;/h3&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;git switch &amp;lt;다른 브랜치&amp;gt;&lt;/span&gt;&lt;span&gt; : 삭제 전 다른 브랜치로 이동&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git branch -D &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 병합되지 않은 브랜치 강제 삭제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git branch -d &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 병합된 브랜치 삭제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;원격 브랜치 삭제 순서:&lt;/span&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;git branch -d &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git push origin --delete &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git fetch&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git pull&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;(필요 시) &lt;/span&gt;&lt;span&gt;git push&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. 브랜치 병합&lt;/span&gt;&lt;/h2&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;git switch &amp;lt;병합할 브랜치&amp;gt;&lt;/span&gt;&lt;span&gt; : 병합할 브랜치로 이동&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git merge &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 해당 브랜치를 현재 브랜치에 병합&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git push origin &amp;lt;현재 브랜치&amp;gt;&lt;/span&gt;&lt;span&gt; : 병합 후 원격 저장소에 반영&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Fast-forward 병합 전략&lt;/span&gt;&lt;/h3&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;git switch dev&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;git pull origin dev&lt;/span&gt;&lt;span&gt; (최신화)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git switch &amp;lt;기능 브랜치&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;git merge dev&lt;/span&gt;&lt;span&gt; (병합)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git push origin &amp;lt;기능 브랜치&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git switch dev&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;git pull&lt;/span&gt;&lt;span&gt; (최신화)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git merge &amp;lt;기능 브랜치&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;git push origin dev&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;dev에서 문제 없으면 main으로 PR 후 병합 진행&lt;/span&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;테스트 완료 후 PR 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;본부장님께 해당 업무 보고&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;main으로 병합 후 먼데이 링크 추가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;해당 내용 요약 작성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;3. 새 브랜치 원격 저장소에 올리기&lt;/span&gt;&lt;/h2&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;git push -u origin &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 브랜치를 원격에 등록&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;이후부터는 &lt;/span&gt;&lt;span&gt;git push&lt;/span&gt;&lt;span&gt; 만으로 푸시 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;4. 브랜치 목록 조회&lt;/span&gt;&lt;/h2&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;git branch -a&lt;/span&gt;&lt;span&gt; : 로컬 및 원격 브랜치 모두 표시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git branch&lt;/span&gt;&lt;span&gt; : 로컬 브랜치만 표시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git branch -r&lt;/span&gt;&lt;span&gt; : 원격 브랜치만 표시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git branch -v&lt;/span&gt;&lt;span&gt; : 각 브랜치의 마지막 커밋 정보 표시&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;5. 롤백 (이미 push한 경우)&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;특정 커밋으로 되돌리기&lt;/span&gt;&lt;/h3&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;git log&lt;/span&gt;&lt;span&gt; : 해시값 찾기 (예: &lt;/span&gt;&lt;span&gt;commit abc123...&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git revert -m 1 &amp;lt;해시값&amp;gt;&lt;/span&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;-m 1&lt;/span&gt;&lt;span&gt; : 병합된 브랜치에서 되돌릴 경우 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;:wq&lt;/span&gt;&lt;span&gt; 입력 후 저장&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git push origin &amp;lt;브랜치명&amp;gt;&lt;/span&gt;&lt;span&gt; : 원격 반영&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;최신 커밋 되돌리기&lt;/span&gt;&lt;/h3&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;git reset --soft HEAD~1&lt;/span&gt;&lt;span&gt; : 가장 최근 커밋 취소 (파일 유지, 스테이지 보존)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git reset --mixed HEAD~1&lt;/span&gt;&lt;span&gt; : 가장 최근 커밋 취소 (파일 유지, 스테이지 해제)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git reset --hard HEAD~1&lt;/span&gt;&lt;span&gt; : 가장 최근 커밋 완전 삭제 (복구 불가)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git push --force&lt;/span&gt;&lt;span&gt; : 강제 푸시 (주의 필요)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;6. 기타 유용한 명령어&lt;/span&gt;&lt;/h2&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;git stash&lt;/span&gt;&lt;span&gt; : 현재 작업을 임시 저장 (커밋 없이 변경사항 숨김)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git stash pop&lt;/span&gt;&lt;span&gt; : 임시 저장된 변경 사항 적용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git rebase -i HEAD~3&lt;/span&gt;&lt;span&gt; : 최근 3개의 커밋을 인터랙티브 리베이스&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git cherry-pick &amp;lt;해시값&amp;gt;&lt;/span&gt;&lt;span&gt; : 특정 커밋을 현재 브랜치로 가져오기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;git log --oneline --graph&lt;/span&gt;&lt;span&gt; : 한 줄씩 그래프 형태로 로그 확인&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>프로젝트(팀, 개인)/GIT</category>
      <category>Branch</category>
      <category>git</category>
      <category>Merge</category>
      <category>reset</category>
      <category>revert</category>
      <category>깃</category>
      <category>명령어</category>
      <category>병합</category>
      <category>브랜치</category>
      <category>삭제</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/453</guid>
      <comments>https://sound-programming.tistory.com/453#entry453comment</comments>
      <pubDate>Tue, 18 Mar 2025 11:32:41 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 [Lv. 2] 서버 증설 횟수 {언어 : JavaScript}</title>
      <link>https://sound-programming.tistory.com/452</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/389479?language=javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/389479?language=javascript&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1741786075643&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/389479?language=javascript&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bdV4z0/hyYqZ82xw3/sZKlgurmkV8knbGwzlBto1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/5v3Qk/hyYrTtH8Rs/OOu3KKzJGkCAKA9xSKxkwK/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/389479?language=javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/389479?language=javascript&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bdV4z0/hyYqZ82xw3/sZKlgurmkV8knbGwzlBto1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/5v3Qk/hyYrTtH8Rs/OOu3KKzJGkCAKA9xSKxkwK/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(players, m, k) {
    const lenP = players.length;
    let answer = 0;

    const servers = Array.from({length: lenP}, () =&amp;gt; 0);
    players.forEach((e, idx) =&amp;gt; {
        if (e &amp;gt;= m) {
            const sai = servers.at(idx);
            const mcedm = Math.floor(e/m);
            if (sai &amp;lt; mcedm) {
                const diff = mcedm - sai;
                answer += diff;
                for (let jdx = idx; jdx &amp;lt; Math.min(idx+k, lenP); jdx++) {
                    servers[jdx] += diff;
                }
            }
        }
    })    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;해당 시간대의 서버 개수(servers.at(idx))와 현재 이용자 수(e)를 비교하고 m명 보다 많은 경우를 걸러준다.&lt;/li&gt;
&lt;li&gt;만약 서버 개수가 적다면 새로 증설하고 k 시간 만큼 servers에 차이(diff)만큼 추가한다.&lt;/li&gt;
&lt;li&gt;answer에는 diff를 한 번만 더해준다.&lt;/li&gt;
&lt;li&gt;마지막으로 answer만 출력하면 끝!&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vg5n7/btsMJfihgSx/e9WkrqUYuPKw3lLEgKuUTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vg5n7/btsMJfihgSx/e9WkrqUYuPKw3lLEgKuUTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vg5n7/btsMJfihgSx/e9WkrqUYuPKw3lLEgKuUTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVg5n7%2FbtsMJfihgSx%2Fe9WkrqUYuPKw3lLEgKuUTk%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;726&quot; height=&quot;150&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오랜만에 문제 푸니까 Array 설정하는 방법도 까먹었다.&lt;/li&gt;
&lt;li&gt;다시 많이 풀어 보는 것이 좋겠다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘</category>
      <category>DP</category>
      <category>Dynamic Programming</category>
      <category>javascript</category>
      <category>Lv. 2</category>
      <category>programmers</category>
      <category>동적계획법</category>
      <category>서버 증설 횟수</category>
      <category>자바스크립트</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/452</guid>
      <comments>https://sound-programming.tistory.com/452#entry452comment</comments>
      <pubDate>Wed, 12 Mar 2025 22:41:28 +0900</pubDate>
    </item>
    <item>
      <title>백준 BRONZE 2 [2745번] 진법 변환  {언어 : Python} [실수 주의]</title>
      <link>https://sound-programming.tistory.com/451</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2745&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/2745&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;메모리 초과 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, b = input().split()
b = int(b)
length = len(n)
c = length - 1
answer = 0
dp = [1] * length
for i in range(1, length):
    dp[i] = dp[i-1] * b
for i in range(length):
    ni = n[i]
    if ni.isdigit():
        answer += ni * dp[c-i]
    else:
        answer += (ord(ni) - 55) * dp[c-i]
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1740439298877&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, b = input().split()
b = int(b)
answer = 0

for char in n:
    if char.isdigit():
        answer = answer * b + int(char)
    else:
        answer = answer * b + (ord(char) - 55)

print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리가 초과된 이유는 숫자를 int로 바꾸는 작업을 하지 않아서였다.&lt;/li&gt;
&lt;li&gt;ni가 isdigit일 때 int로 바꾸면 40ms가 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;97&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ODjx9/btsMtoA9QJb/mIlV6giGB6pkm78pKybK11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ODjx9/btsMtoA9QJb/mIlV6giGB6pkm78pKybK11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ODjx9/btsMtoA9QJb/mIlV6giGB6pkm78pKybK11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FODjx9%2FbtsMtoA9QJb%2FmIlV6giGB6pkm78pKybK11%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;657&quot; height=&quot;97&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;97&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/다시 풀어 보기</category>
      <category>2745</category>
      <category>Baekjoon</category>
      <category>Python</category>
      <category>구현</category>
      <category>문자열</category>
      <category>백준</category>
      <category>수학</category>
      <category>진법 변환</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/451</guid>
      <comments>https://sound-programming.tistory.com/451#entry451comment</comments>
      <pubDate>Tue, 25 Feb 2025 08:27:15 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 5 [11729번] 하노이 탑 이동 순서  {언어 : Python} [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/450</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11729&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/11729&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
dp = [0] * 21
dp[1] = 1
for i in range(2, 21):
    dp[i] = dp[i-1] * 2 + 1
print(dp[n])
def hanoi(number, start, end, assist):
    if number == 1:
        print(start, end)
        return
    else:
        hanoi(number-1, start, assist, end)
        print(start, end)
        hanoi(number-1, assist, end, start)
hanoi(n, 1, 3, 2)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&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;/li&gt;
&lt;li&gt;숫자가 1인 경우 한 번만 이동하면 된다.&lt;/li&gt;
&lt;li&gt;나머지는 이 풀이를 보면 좋을 것 같다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mgyo.tistory.com/185&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mgyo.tistory.com/185&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1739518286536&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;'하노이의 탑' 이해하기 (feat. 재귀 함수)&quot; data-og-description=&quot;들어가며 하노이의 탑 문제 소개 문제 정의 아이디어 얻기 아이디어 재귀 출발점, 도착점, 경유점 문제 분해 실제 코드 번외 : 원반의 개수에 따른 총 이동횟수 구하기 마무리 자료 출처 https://www&quot; data-og-host=&quot;mgyo.tistory.com&quot; data-og-source-url=&quot;https://mgyo.tistory.com/185&quot; data-og-url=&quot;https://mgyo.tistory.com/185&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/60hbD/hyYfGaptjQ/1MCxPEFaXw1FFnKaq0YDPk/img.gif?width=300&amp;amp;height=117&amp;amp;face=0_0_300_117,https://scrap.kakaocdn.net/dn/dYgnUp/hyYfVZJaKH/E6rdmGgEC1Sb9kRlXDFrk0/img.gif?width=300&amp;amp;height=117&amp;amp;face=0_0_300_117,https://scrap.kakaocdn.net/dn/eaI55h/hyYfE4KjzK/uGoRsIJ0wnr2NqvQTCnQWK/img.png?width=1800&amp;amp;height=388&amp;amp;face=0_0_1800_388&quot;&gt;&lt;a href=&quot;https://mgyo.tistory.com/185&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mgyo.tistory.com/185&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/60hbD/hyYfGaptjQ/1MCxPEFaXw1FFnKaq0YDPk/img.gif?width=300&amp;amp;height=117&amp;amp;face=0_0_300_117,https://scrap.kakaocdn.net/dn/dYgnUp/hyYfVZJaKH/E6rdmGgEC1Sb9kRlXDFrk0/img.gif?width=300&amp;amp;height=117&amp;amp;face=0_0_300_117,https://scrap.kakaocdn.net/dn/eaI55h/hyYfE4KjzK/uGoRsIJ0wnr2NqvQTCnQWK/img.png?width=1800&amp;amp;height=388&amp;amp;face=0_0_1800_388');&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;'하노이의 탑' 이해하기 (feat. 재귀 함수)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;들어가며 하노이의 탑 문제 소개 문제 정의 아이디어 얻기 아이디어 재귀 출발점, 도착점, 경유점 문제 분해 실제 코드 번외 : 원반의 개수에 따른 총 이동횟수 구하기 마무리 자료 출처 https://www&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mgyo.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brTFbC/btsMjB7o4h2/hSRCauNxr6rcqeHhxJ0kN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brTFbC/btsMjB7o4h2/hSRCauNxr6rcqeHhxJ0kN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brTFbC/btsMjB7o4h2/hSRCauNxr6rcqeHhxJ0kN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrTFbC%2FbtsMjB7o4h2%2FhSRCauNxr6rcqeHhxJ0kN0%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;805&quot; height=&quot;152&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/ul&gt;</description>
      <category>알고리즘/다시 풀어 보기</category>
      <category>11729</category>
      <category>Baekjoon</category>
      <category>Python</category>
      <category>백준</category>
      <category>재귀</category>
      <category>파이썬</category>
      <category>하노이 탑 이동 순서</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/450</guid>
      <comments>https://sound-programming.tistory.com/450#entry450comment</comments>
      <pubDate>Fri, 14 Feb 2025 16:32:05 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 5 [9251번] LCS  {언어 : Python} [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/449</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9251&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/9251&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드 1&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = input()
b = input()
lenA = len(a)
lenB = len(b)
dp = [[0] * (lenA+1) for _ in range(lenB+1)]
maxLength = 0
for i in range(lenB):
    alphaB = b[i]
    for j in range(lenA):
        alphaA = a[j]
        if alphaA == alphaB:
            dp[i][j] += dp[i-1][j-1] + 1
        else:
            dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        maxLength = max(maxLength, dp[i][j])
print(maxLength)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드 2&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1739421086747&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = input()
b = input()
lenA = len(a)
lenB = len(b)
prevDp = [0] * (lenB+1)
for i in range(1, lenA+1):
    nextDp = [0] * (lenB+1)
    alphaA = a[i-1]
    for j in range(1, lenB+1):
        alphaB = b[j-1]
        if alphaA == alphaB:
            nextDp[j-1] = prevDp[j-2] + 1
        else:
            nextDp[j-1] = max(prevDp[j-1], nextDp[j-2])
    prevDp = nextDp
print(max(prevDp))&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;lcs라고 &lt;b&gt;최장 공통 부분수열(Longest Common Subsequence) &lt;/b&gt;또는&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;최장 공통 문자열(Longest Common Substring)&lt;/b&gt;을 사용했다.&lt;/li&gt;
&lt;li&gt;dp[i][j]에 값을 더해가면서 가장 긴 부분의 길이를 찾는다.
&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;/li&gt;
&lt;li&gt;알파벳이 같을 경우 대각선의 dp[i-1][j-1]에 1을 더해준다.&lt;/li&gt;
&lt;li&gt;다를 경우 상, 좌에 있는 dp[i-1][j]와 dp[i][j-1] 중 큰 값을 넣는다.&lt;/li&gt;
&lt;li&gt;dp에 가장 큰 값이 공통되는 가장 긴 길이이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sound-programming.tistory.com/352&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sound-programming.tistory.com/352&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1739421384012&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Softeer [Level 3] 효도 여행 {언어 : JavaScript} [시간초과 해결]&quot; data-og-description=&quot;문제 링크https://softeer.ai/practice/7649&amp;nbsp;Softeer - 현대자동차그룹 SW인재확보플랫폼&amp;nbsp;softeer.ai정답 코드const readline = require('readline');const rl = readline.createInterface({ input: process.stdin, output: process.stdout,});// 트&quot; data-og-host=&quot;sound-programming.tistory.com&quot; data-og-source-url=&quot;https://sound-programming.tistory.com/352&quot; data-og-url=&quot;https://sound-programming.tistory.com/352&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iMtRI/hyYceft2rU/taecnxS5VYK3EjbnjbvzR1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/liUvI/hyYfPkJzJz/vmmEkcS9oPCQJY8tejmuD0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/c2DpYl/hyYfUGmYTy/FkZY3CikxJ74GWGZKE7dNK/img.jpg?width=538&amp;amp;height=538&amp;amp;face=0_0_538_538&quot;&gt;&lt;a href=&quot;https://sound-programming.tistory.com/352&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sound-programming.tistory.com/352&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iMtRI/hyYceft2rU/taecnxS5VYK3EjbnjbvzR1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/liUvI/hyYfPkJzJz/vmmEkcS9oPCQJY8tejmuD0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/c2DpYl/hyYfUGmYTy/FkZY3CikxJ74GWGZKE7dNK/img.jpg?width=538&amp;amp;height=538&amp;amp;face=0_0_538_538');&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;Softeer [Level 3] 효도 여행 {언어 : JavaScript} [시간초과 해결]&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;문제 링크https://softeer.ai/practice/7649&amp;nbsp;Softeer - 현대자동차그룹 SW인재확보플랫폼&amp;nbsp;softeer.ai정답 코드const readline = require('readline');const rl = readline.createInterface({ input: process.stdin, output: process.stdout,});// 트&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sound-programming.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@emplam27/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-LCS-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Longest-Common-Substring%EC%99%80-Longest-Common-Subsequence&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@emplam27/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-LCS-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Longest-Common-Substring%EC%99%80-Longest-Common-Subsequence&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1739421415251&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[알고리즘] 그림으로 알아보는 LCS 알고리즘 - Longest Common Substring와 Longest Common Subsequence&quot; data-og-description=&quot;LCS는 주로 최장 공통 부분수열(Longest Common Subsequence)을 말합니다만, 최장 공통 문자열(Longest Common Substring)을 말하기도 합니다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@emplam27/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-LCS-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Longest-Common-Substring%EC%99%80-Longest-Common-Subsequence&quot; data-og-url=&quot;https://velog.io/@emplam27/알고리즘-그림으로-알아보는-LCS-알고리즘-Longest-Common-Substring와-Longest-Common-Subsequence&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b9Zd3h/hyYfKRgmsJ/dae3GUpUdjgKD6gjkLMOe0/img.jpg?width=756&amp;amp;height=394&amp;amp;face=0_0_756_394,https://scrap.kakaocdn.net/dn/bcOh4j/hyYachF2q3/4YbUS6akc9Ok1l8pQphkxk/img.jpg?width=756&amp;amp;height=394&amp;amp;face=0_0_756_394,https://scrap.kakaocdn.net/dn/HUiYk/hyYccWepn2/PRSigBdXeSIW2uxEc6f550/img.png?width=1125&amp;amp;height=1885&amp;amp;face=0_0_1125_1885&quot;&gt;&lt;a href=&quot;https://velog.io/@emplam27/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-LCS-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Longest-Common-Substring%EC%99%80-Longest-Common-Subsequence&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@emplam27/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-LCS-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Longest-Common-Substring%EC%99%80-Longest-Common-Subsequence&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b9Zd3h/hyYfKRgmsJ/dae3GUpUdjgKD6gjkLMOe0/img.jpg?width=756&amp;amp;height=394&amp;amp;face=0_0_756_394,https://scrap.kakaocdn.net/dn/bcOh4j/hyYachF2q3/4YbUS6akc9Ok1l8pQphkxk/img.jpg?width=756&amp;amp;height=394&amp;amp;face=0_0_756_394,https://scrap.kakaocdn.net/dn/HUiYk/hyYccWepn2/PRSigBdXeSIW2uxEc6f550/img.png?width=1125&amp;amp;height=1885&amp;amp;face=0_0_1125_1885');&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;[알고리즘] 그림으로 알아보는 LCS 알고리즘 - Longest Common Substring와 Longest Common Subsequence&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;LCS는 주로 최장 공통 부분수열(Longest Common Subsequence)을 말합니다만, 최장 공통 문자열(Longest Common Substring)을 말하기도 합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 풀이는 2차원 배열로 풀어봤고&lt;/li&gt;
&lt;li&gt;2번 풀이는 1차원 배열로 풀어봤다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdgeKA/btsMh3WkDU4/O2KAiPkmDvu58l7Kb5fvvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdgeKA/btsMh3WkDU4/O2KAiPkmDvu58l7Kb5fvvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdgeKA/btsMh3WkDU4/O2KAiPkmDvu58l7Kb5fvvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdgeKA%2FbtsMh3WkDU4%2FO2KAiPkmDvu58l7Kb5fvvK%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;890&quot; height=&quot;148&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2번 풀이가 메모리도 작고 시간복잡도도 낮아서 더 효율적인 것을 알 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/다시 풀어 보기</category>
      <category>9251</category>
      <category>Baekjoon</category>
      <category>DP</category>
      <category>LCS</category>
      <category>Python</category>
      <category>다이나믹 프로그래밍</category>
      <category>문자열</category>
      <category>백준</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/449</guid>
      <comments>https://sound-programming.tistory.com/449#entry449comment</comments>
      <pubDate>Thu, 13 Feb 2025 13:38:41 +0900</pubDate>
    </item>
    <item>
      <title>백준 SILVER 3 [3273번] 두 수의 합  {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/448</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3273&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/3273&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
arr = sorted(list(map(int, input().split())))
val = int(input())
left = 0
right = n - 1
answer = 0
while left &amp;lt; right:
    tmp = arr[left] + arr[right]
    if tmp == val:
        left += 1
        right -= 1
        answer += 1
    elif tmp &amp;gt; val:
        right -= 1
    else:
        left += 1
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&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;/li&gt;
&lt;li&gt;정렬한 배열의 좌 우측에서 값을 가져온다.&lt;/li&gt;
&lt;li&gt;값이 원하는 값과 같다면 좌를 키우고 우를 낮춰서 범위를 줄여준다.&lt;/li&gt;
&lt;li&gt;값이 작다면 좌측에서 값을 키워야 하므로 좌를 키운다.&lt;/li&gt;
&lt;li&gt;값이 크다면 우측에서 값을 낮춰야 하므로 우를 낮춘다.&lt;/li&gt;
&lt;li&gt;좌우 값이 같지 않을 때 까지 한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;인덱스가 겹치지 않는 서로 다른 양의 정수의 쌍을 찾는 문제&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;값이 같을 때만 answer에 1을 더해주고 이를 출력하면 끝!&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 사람 풀이가 60ms도 내 풀이 84ms 보다 빠르기에 확인해봤다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1739254840331&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, val):
    arrSet = set(arr)
    cnt = 0
    for num in arr:
        if val - num in arrSet:
            cnt += 1
    return cnt // 2

n = int(input())
arr = list(map(int, input().split()))
val = int(input())
print(solution(arr, val))&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속도는 빠르지만 메모리가 올라간 것을 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;시간 복잡도는 낮출 수 있지만 set를 사용하면서 공간 복잡도를 키웠다고 생각한다.&lt;/li&gt;
&lt;li&gt;둘 중에 어떤 알고리즘을 선택하는 것은 자유이나 상황에 맞는 알고리즘을 선택하는 개발자가 되겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wznro/btsMfeRhkDG/qSqOXGvk3hHO4yJQiD4tL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wznro/btsMfeRhkDG/qSqOXGvk3hHO4yJQiD4tL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wznro/btsMfeRhkDG/qSqOXGvk3hHO4yJQiD4tL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWznro%2FbtsMfeRhkDG%2FqSqOXGvk3hHO4yJQiD4tL0%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;898&quot; height=&quot;238&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>3273</category>
      <category>Baekjoon</category>
      <category>Python</category>
      <category>Two Pointer</category>
      <category>두 수의 합</category>
      <category>세트</category>
      <category>실버</category>
      <category>정렬</category>
      <category>투 포인터</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/448</guid>
      <comments>https://sound-programming.tistory.com/448#entry448comment</comments>
      <pubDate>Tue, 11 Feb 2025 15:22:24 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 5 [2565번] 전깃줄  {언어 : Python} [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/447</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2565&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/2565&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline
n = int(input())
lines = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x:x[1])
dp = [1] * n
for i in range(1, n):
    si, ti = lines[i]
    for j in range(i):
        sj, tj = lines[j]
        if sj &amp;lt; si:
            dp[i] = max(dp[j]+1, dp[i])

print(n - max(dp))&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;(시작점, 끝점)을 입력받고 &lt;b&gt;끝나는 지점 기준으로 정렬&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;정렬은 &lt;b&gt;그리디 + DP 조합을 활용하기 위한 사전 작업&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DP 배열 정의 및 초기화&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;dp[i]는 &lt;b&gt;i번째 선분을 포함했을 때 겹치지 않는 최대 선분 개수&lt;/b&gt;를 저장한다.&lt;/li&gt;
&lt;li&gt;모든 값은 최소 1이므로 [1] * n으로 초기화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DP 점화식 적용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이중 반복문을 돌며 sj &amp;lt; si 조건을 만족하는 경우 dp[i] = max(dp[j] + 1, dp[i])로 갱신한다.&lt;/li&gt;
&lt;li&gt;즉, &lt;b&gt;선분이 겹치지 않는 경우&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;max(dp)는 &lt;b&gt;최대 겹치지 않는 선분 개수&lt;/b&gt;를 의미한다.&lt;/li&gt;
&lt;li&gt;전체 개수 n에서 max(dp)를 빼면, &lt;b&gt;제거해야 할 최소 선분 개수&lt;/b&gt;가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;lis 알고리즘&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1739172067382&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from bisect import bisect_left

import sys
input = sys.stdin.readline
n = int(input())
lines = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x:x[1])

lis = []
for si, _ in lines:
    pos = bisect_left(lis, si)  # lis에서 si가 들어갈 위치 찾기
    if pos == len(lis):
        lis.append(si)  # 새로운 원소 추가
    else:
        lis[pos] = si  # 기존 원소 교체 (LIS 유지)

print(n - len(lis))  # 제거해야 하는 최소 선분 개수&lt;/code&gt;&lt;/pre&gt;
&lt;p 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;1426&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/O07jE/btsMdnnPd0O/85jsyRI8dv2Wk6oUTChU6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/O07jE/btsMdnnPd0O/85jsyRI8dv2Wk6oUTChU6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/O07jE/btsMdnnPd0O/85jsyRI8dv2Wk6oUTChU6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FO07jE%2FbtsMdnnPd0O%2F85jsyRI8dv2Wk6oUTChU6k%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;1426&quot; height=&quot;147&quot; data-origin-width=&quot;1426&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;기존 코드 (O(n^2))&lt;/b&gt;: DP를 이용해 &lt;b&gt;최대 겹치지 않는 선분 개수&lt;/b&gt;를 구한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개선 코드 (O(n log n))&lt;/b&gt;: 이분 탐색 기반 &lt;b&gt;LIS 알고리즘&lt;/b&gt;을 활용하여 최적화 가능하다.&lt;/li&gt;
&lt;li&gt;print(n - max(dp))를 통해 &lt;b&gt;제거해야 할 최소 선분 개수&lt;/b&gt;를 출력하는 것이 핵심이다.&lt;/li&gt;
&lt;li&gt;겹치는 부분을 구하려고 했으나 안 겹치는 부분의 개수를 구하면 쉬워지는 문제였다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/다시 풀어 보기</category>
      <category>2565</category>
      <category>Baekjoon</category>
      <category>DP</category>
      <category>Dynamic Programming</category>
      <category>Lis</category>
      <category>Python</category>
      <category>다이나믹 프로그래밍</category>
      <category>백준</category>
      <category>전깃줄</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/447</guid>
      <comments>https://sound-programming.tistory.com/447#entry447comment</comments>
      <pubDate>Mon, 10 Feb 2025 16:23:36 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 5 [12919번] A와 B 2  {언어 : Python} [반례 포함]</title>
      <link>https://sound-programming.tistory.com/446</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12919&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/12919&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s = input()
t = input()
lenS = len(s)
lenT = len(t)
answer = 0

def isIncluded(arr):
    normarlString = &quot;&quot;.join(arr)
    reversString = &quot;&quot;.join(arr[::-1])
    return normarlString in t or reversString in t

def dfs(length, arr):
    global answer
    if answer:
        return

    if length == lenT:
        string = &quot;&quot;.join(arr)
        if string == t:
            answer = 1
        return

    if isIncluded(arr+[&quot;A&quot;]):
        dfs(length+1, arr+[&quot;A&quot;])
    if isIncluded([&quot;B&quot;] + arr[::-1]):
        dfs(length+1, [&quot;B&quot;] + arr[::-1])

dfs(lenS, list(s))
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;길이가 lenT와 같아지면 종료되는 재귀함수를 만든다.&lt;/li&gt;
&lt;li&gt;만약 이미 바꿀 수 있음을 확인했다면 종료시킨다.&lt;/li&gt;
&lt;li&gt;재귀가 최대 2^50 = 1,125,899,906,842,624번 연산이 될 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;따라서 바꾸려고 하는 문자열이 t에 있는지 확인하고 재귀를 돌린다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;여기서 문자열을 뒤집어서도 확인 해봐야 한다.&lt;/li&gt;
&lt;li&gt;그렇지 않으면 다음과 같은 반례가 나온다.&lt;/li&gt;
&lt;li&gt;s = AB&lt;/li&gt;
&lt;li&gt;t = BABB&lt;/li&gt;
&lt;li&gt;답 = 1&lt;/li&gt;
&lt;li&gt;오답 = 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;연산이 끝나면 answer를 출력한다&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baCWrP/btsMbUSU4yL/qY23SjkQUeZkFWO2WxGkTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baCWrP/btsMbUSU4yL/qY23SjkQUeZkFWO2WxGkTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baCWrP/btsMbUSU4yL/qY23SjkQUeZkFWO2WxGkTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaCWrP%2FbtsMbUSU4yL%2FqY23SjkQUeZkFWO2WxGkTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1132&quot; height=&quot;52&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/ul&gt;</description>
      <category>알고리즘</category>
      <category>12919</category>
      <category>a와 b 2</category>
      <category>Baekjoon</category>
      <category>Python</category>
      <category>문자열</category>
      <category>반례</category>
      <category>백준</category>
      <category>브루트포스 알고리즘</category>
      <category>재귀</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/446</guid>
      <comments>https://sound-programming.tistory.com/446#entry446comment</comments>
      <pubDate>Fri, 7 Feb 2025 16:36:04 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 4 [10830번] 행렬 제곱  {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/445</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10830&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/10830&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline
n, b = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(n)]
optimization = dict()
# matrix의 원소가 1000이하이기 때문에 처음부터 걸러준다.
for i in range(n):
    for j in range(n):
        matrix[i][j] %= 1000
optimization[1] = matrix

# cal = calculation
def cal(leftM, rightM):
    newM = [[0] * n for _ in range(n)]
    for i in range(n):
        for j in range(n):
            for k in range(n):
                newM[i][j] += (leftM[i][k] * rightM[k][j]) % 1000
            newM[i][j] %= 1000
    return newM
# dac = divide and conquer
def dac(depth):
    if depth == 1:
        return matrix
    elif depth == 2:
        return cal(matrix, matrix)
    else:
        if optimization.get(depth, 0) == 0:
            if depth % 2:
                optimization[depth] = cal(dac(depth//2+1), dac(depth//2))
            else:
                optimization[depth] = cal(dac(depth//2), dac(depth//2))
        return optimization[depth]
answer = dac(b)
for a in answer:
    print(*a)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&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;/li&gt;
&lt;li&gt;만약 10제곱이라면
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;2등분해서 5 5로 나누고&lt;/li&gt;
&lt;li&gt;5를 2 3으로 나누고&lt;/li&gt;
&lt;li&gt;2는 1 1&lt;/li&gt;
&lt;li&gt;3은 다시 2 1&lt;/li&gt;
&lt;li&gt;2는 1 1&lt;/li&gt;
&lt;li&gt;이렇게 나눠서 가장 깊숙한 지점부터 계산해서 올라 온다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;만약 n제곱이 존재하면 계산할 필요가 없이 dictionary에서 찾을 수 있도록 최적화 했다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이렇게 하지 않았다면 시간초과가 걸렸을 것이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;맨 처음에 1000으로 나누어 떨어뜨리는 이유
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;주어진 행렬의 원소가 1 &amp;lt;= elem &amp;lt;= 1000 이고 결과값은 원소 모두가 1000으로 나누어 떨어진 값이어야 하기 때문이다.&lt;/li&gt;
&lt;li&gt;이렇게 안 하면 거듭제곱이 1이고 원소가 다 1000일 경우 틀린 값이 나오게 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;계산이 완료되면 answer에 넣고 출력하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1131&quot; data-origin-height=&quot;51&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHmdJM/btsL5M3jTqe/gEiTkj4rJbURbpWodqgay1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHmdJM/btsL5M3jTqe/gEiTkj4rJbURbpWodqgay1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHmdJM/btsL5M3jTqe/gEiTkj4rJbURbpWodqgay1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHmdJM%2FbtsL5M3jTqe%2FgEiTkj4rJbURbpWodqgay1%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;1131&quot; height=&quot;51&quot; data-origin-width=&quot;1131&quot; data-origin-height=&quot;51&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;b의 값이 &lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;100,000,000,000이었기 때문에 분할 정복을 유추할 수 있었다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot;&gt;이미 계산한 과정은 생략하고 바로 값을 찾을 수 있도록 딕셔너리에 넣는 방법을 배웠다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>10830</category>
      <category>Baekjoon</category>
      <category>Python</category>
      <category>분할 정복을 이용한 거듭제곱</category>
      <category>분할정복</category>
      <category>선형대수학</category>
      <category>수학</category>
      <category>파이썬</category>
      <category>행렬 제곱</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/445</guid>
      <comments>https://sound-programming.tistory.com/445#entry445comment</comments>
      <pubDate>Tue, 4 Feb 2025 17:23:54 +0900</pubDate>
    </item>
    <item>
      <title>[NextJS] favicon 바꾸기</title>
      <link>https://sound-programming.tistory.com/444</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;lt; 내용 &amp;gt;&amp;nbsp;&lt;/b&gt;&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;favicon을 바꿀 수 있다.&lt;/li&gt;
&lt;li&gt;png, jpg 파일을 ico 확장자로 변환할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&amp;nbsp;&amp;lt; 목차 &amp;gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;favicon 바꾸기&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&amp;nbsp;1. favicon 바꾸기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvqgqw/btsL2mWrfRe/W7bkX3KSBo5ycTb7lUhtg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvqgqw/btsL2mWrfRe/W7bkX3KSBo5ycTb7lUhtg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvqgqw/btsL2mWrfRe/W7bkX3KSBo5ycTb7lUhtg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdvqgqw%2FbtsL2mWrfRe%2FW7bkX3KSBo5ycTb7lUhtg0%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;1918&quot; height=&quot;443&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIyEpn/btsL0QLfplC/7PYKpvbLqCAPPuvwkrOTV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIyEpn/btsL0QLfplC/7PYKpvbLqCAPPuvwkrOTV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIyEpn/btsL0QLfplC/7PYKpvbLqCAPPuvwkrOTV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIyEpn%2FbtsL0QLfplC%2F7PYKpvbLqCAPPuvwkrOTV1%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;967&quot; height=&quot;693&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위와 같이 favicon.ico를 원하는 이미지로 바꾸면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;원하는 이미지 (png, jpg 등)을 선택한다.&lt;/li&gt;
&lt;li&gt;이미지를 ico확장자로 변경한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;png ico 변환으로 구글 검색하면 쉽게 찾을 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;ico로 변경한 이미지의 이름을 favicon으로 바꾼다.&lt;/li&gt;
&lt;li&gt;원래 있던 favicon과 바꿔치기 하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.freeconvert.com/ko/png-to-ico&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.freeconvert.com/ko/png-to-ico&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737807471916&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;ICO PNG 으로 변환기 - FreeConvert.com&quot; data-og-description=&quot;PNG를 ICO로 변환하는 변환기. 온라인에서 최고 품질로 PNG를 ICO로 변환하는 가장 좋은 방법입니다. 이 도구는 무료이며 안전하며 모든 웹 브라우저에서 작동합니다.&quot; data-og-host=&quot;www.freeconvert.com&quot; data-og-source-url=&quot;https://www.freeconvert.com/ko/png-to-ico&quot; data-og-url=&quot;https://www.freeconvert.com/ko/png-to-ico&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.freeconvert.com/ko/png-to-ico&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.freeconvert.com/ko/png-to-ico&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;ICO PNG 으로 변환기 - FreeConvert.com&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;PNG를 ICO로 변환하는 변환기. 온라인에서 최고 품질로 PNG를 ICO로 변환하는 가장 좋은 방법입니다. 이 도구는 무료이며 안전하며 모든 웹 브라우저에서 작동합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.freeconvert.com&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;</description>
      <category>프론트엔드/Next.js</category>
      <category>favicon</category>
      <category>FreeConvert</category>
      <category>ico</category>
      <category>NextJS</category>
      <category>png</category>
      <category>변환</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/444</guid>
      <comments>https://sound-programming.tistory.com/444#entry444comment</comments>
      <pubDate>Sat, 25 Jan 2025 21:18:20 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 5 [12865번] 평범한 배낭  {언어 : Python} [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/443</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12865&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/12865&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline
n, k = map(int, input().split())
dp = [[0] * (k+1) for _ in range(n+1)]
for i in range(1, n+1):
    w, v = map(int, input().split())
    for j in range(1, k+1):
        if j &amp;gt;= w:
            dp[i][j] = max(v+dp[i-1][j-w], dp[i-1][j])
        else:
            dp[i][j] = dp[i-1][j]
print(dp[n][k])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KRENF/btsLYIUuID9/zH53hvxHQdnhpkfgMGK2rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KRENF/btsLYIUuID9/zH53hvxHQdnhpkfgMGK2rk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KRENF/btsLYIUuID9/zH53hvxHQdnhpkfgMGK2rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKRENF%2FbtsLYIUuID9%2FzH53hvxHQdnhpkfgMGK2rk%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;851&quot; height=&quot;92&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;br /&gt;&lt;/b&gt;&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;DP 배열의 의미&lt;/b&gt;:&lt;br /&gt;&lt;span&gt;&lt;span&gt;dp[i][j]dp[i][j]&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;j&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;는 &lt;b&gt;앞에서 &lt;span&gt;&lt;span&gt;ii&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;번째 물건까지 고려했을 때&lt;/b&gt;, 배낭의 최대 무게가 &lt;span&gt;&lt;span&gt;jj&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;j&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&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-origin-width=&quot;636&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kscm6/btsL0FBH4gi/v8hDv50iGvyQUvKIGP51pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kscm6/btsL0FBH4gi/v8hDv50iGvyQUvKIGP51pK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kscm6/btsL0FBH4gi/v8hDv50iGvyQUvKIGP51pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKscm6%2FbtsL0FBH4gi%2Fv8hDv50iGvyQUvKIGP51pK%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;636&quot; height=&quot;242&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J0Eyg/btsLYN2yimd/DXTyJepmpKGKAuVzZR9600/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J0Eyg/btsLYN2yimd/DXTyJepmpKGKAuVzZR9600/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J0Eyg/btsLYN2yimd/DXTyJepmpKGKAuVzZR9600/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ0Eyg%2FbtsLYN2yimd%2FDXTyJepmpKGKAuVzZR9600%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;663&quot; height=&quot;235&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;238&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dodZv2/btsL0yQm5Z0/WaYnvSbVEtHssT73GLz0V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dodZv2/btsL0yQm5Z0/WaYnvSbVEtHssT73GLz0V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dodZv2/btsL0yQm5Z0/WaYnvSbVEtHssT73GLz0V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdodZv2%2FbtsL0yQm5Z0%2FWaYnvSbVEtHssT73GLz0V0%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;645&quot; height=&quot;238&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/saARe/btsLZkr4w6M/w3e1bZkWyWdYfJqEIMgrg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/saARe/btsLZkr4w6M/w3e1bZkWyWdYfJqEIMgrg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/saARe/btsLZkr4w6M/w3e1bZkWyWdYfJqEIMgrg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsaARe%2FbtsLZkr4w6M%2Fw3e1bZkWyWdYfJqEIMgrg1%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;665&quot; height=&quot;245&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JFEpR/btsLZawqj4R/P6Zj4G8uXC43z4AHDPuqjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JFEpR/btsLZawqj4R/P6Zj4G8uXC43z4AHDPuqjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JFEpR/btsLZawqj4R/P6Zj4G8uXC43z4AHDPuqjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJFEpR%2FbtsLZawqj4R%2FP6Zj4G8uXC43z4AHDPuqjk%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;665&quot; height=&quot;245&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오랜만에 dp를 푸는데 어려웠다.&lt;/li&gt;
&lt;li&gt;dp일 거라고 추측은 했지만 방법을 잘 몰랐다.&lt;/li&gt;
&lt;li&gt;dp가 2차원 배열로도 만들 수 있다는 부분을 간과했다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/다시 풀어 보기</category>
      <category>12865</category>
      <category>backpack</category>
      <category>Baekjoon</category>
      <category>DP</category>
      <category>Dynamic Programming</category>
      <category>Python</category>
      <category>다이나믹 프로그래밍</category>
      <category>배낭 문제</category>
      <category>파이썬</category>
      <category>평범한 배낭</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/443</guid>
      <comments>https://sound-programming.tistory.com/443#entry443comment</comments>
      <pubDate>Fri, 24 Jan 2025 15:13:37 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 3 [15684번] 사다리 조작  {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/442</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15684&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/15684&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline
n, m, h = map(int, input().split())
board = [[0] * (n+1) for _ in range(h+1)]

for _ in range(m):
    row, column = map(int, input().split())
    board[row][column] = column + 1
    board[row][column+1] = column

def check(board, destination):
    c = destination
    for r in range(1, h+1):
        if board[r][c]:
            c = board[r][c]
    if c == destination:
        return True
    return False

def marking(board, destination):
    c = destination
    for r in range(1, h+1):
        if board[r][c]:
            c = board[r][c]
        else:
            board[r][c] = -1

def backtracking(board, column, cnt):
    global answer
    # 가지치기
    if answer &amp;lt;= cnt:
        return
    if column &amp;gt; n:
        answer = cnt
        return
    if check(board, column):
        marking(board, column)
        return backtracking(board, column+1, cnt)

    # 설치
    c = column
    for r in range(1, h+1):
        if board[r][c] &amp;gt; 0:
            c = board[r][c]
        else:
            right = c + 1
            left = c - 1
            # 왼쪽 설치
            # 왼쪽에 없어야 하고
            # 오른쪽이 n 이거나 오른쪽에서 현재 지점으로 선이 없어야 한다.
            if c &amp;gt; 1 and board[r][left] == 0 and ((right &amp;lt;= n and board[r][right] != c) or right &amp;gt; n):
                leftBoard = [line[:] for line in board]
                leftBoard[r][left] = c
                leftBoard[r][c] = left
                backtracking(leftBoard, column, cnt+1)
            if c &amp;lt; n and board[r][right] == 0 and ((left &amp;gt;= 1 and board[r][left] != c) or left &amp;lt; 1):
                rightBoard = [line[:] for line in board]
                rightBoard[r][right] = c
                rightBoard[r][c] = right
                backtracking(rightBoard, column, cnt+1)
answer = 4
backtracking(board, 1, 0)
print(answer if answer &amp;lt; 4 else -1)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1572&quot; data-origin-height=&quot;42&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kL34j/btsLYMOPzwH/IjPLSxRavCw3LkOU3vlSj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kL34j/btsLYMOPzwH/IjPLSxRavCw3LkOU3vlSj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kL34j/btsLYMOPzwH/IjPLSxRavCw3LkOU3vlSj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkL34j%2FbtsLYMOPzwH%2FIjPLSxRavCw3LkOU3vlSj0%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;1572&quot; height=&quot;42&quot; data-origin-width=&quot;1572&quot; data-origin-height=&quot;42&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;효율적인 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1737633179796&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sys import stdin

def back_tracking(n: int, max_cnt: int):
    global ladder, answer, H, N

    if answer!=-1:
        return
    
    cur_cnt = check()
    if cur_cnt+(max_cnt-n)*2 &amp;lt; N:
        return
    
    if n==max_cnt:
        if cur_cnt==N:
            answer = max_cnt
        return
    
    for h in range(1, H+1):
        for i in range(1, N):
            if ladder[h][i]==0 and ladder[h][i+1]==0:
                ladder[h][i], ladder[h][i+1] = i+1, i
                back_tracking(n+1, max_cnt)
                ladder[h][i], ladder[h][i+1] = 0, 0

def check() -&amp;gt; int:
    global ladder, N, H
    matched = 0
    for i in range(1, N+1):
        cur_i = i
        for h in range(1, H+1):
            if ladder[h][cur_i]!=0:
                cur_i = ladder[h][cur_i]
        if cur_i==i:
            matched += 1
    return matched

N, M, H = map(int, stdin.readline().split())
ladder = [[0]*(N+1) for _ in range(H+1)]
for i in stdin:
    a, b = map(int, i.split())
    ladder[a][b] = b+1
    ladder[a][b+1] = b
answer = -1
for cnt in range(4):
    back_tracking(0, cnt)
    if answer != -1:
        break
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;50&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4ecwf/btsLZc7yorW/XVLiKtHRMxEiHZ8lKQZwh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4ecwf/btsLZc7yorW/XVLiKtHRMxEiHZ8lKQZwh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4ecwf/btsLZc7yorW/XVLiKtHRMxEiHZ8lKQZwh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4ecwf%2FbtsLZc7yorW%2FXVLiKtHRMxEiHZ8lKQZwh1%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;1125&quot; height=&quot;50&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;50&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예를들어 3 2 라면&lt;/li&gt;
&lt;li&gt;3번 세로줄의 2번 행에서 우로 선이 이어진다.&lt;/li&gt;
&lt;li&gt;board[3][2] = 2 + 1
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;즉 오른쪽으로 이동할 수 있도록 방향을 적는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;board[3][3] = 2
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;오른쪽에서도 이동할 수 있도록 이쪽 지점을 적는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;세로 줄 하나가 출발점과 끝점이 같은지 확인하는 함수를 만든다.&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;li&gt;백트래킹을 실시한다.&lt;/li&gt;
&lt;li&gt;실시후 answer의 값이 4이면 불가능하다는 말로 -1 아닌 경우는 answer값을 출력하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be65GS/btsLX9cLQUS/do9ZJkOeLiIceMQa9zLQB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be65GS/btsLX9cLQUS/do9ZJkOeLiIceMQa9zLQB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be65GS/btsLX9cLQUS/do9ZJkOeLiIceMQa9zLQB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe65GS%2FbtsLX9cLQUS%2Fdo9ZJkOeLiIceMQa9zLQB0%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;738&quot; height=&quot;417&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;417&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;li&gt;일단 풀었으면 된다라는 마인드가 아닌 왜 이렇게 풀었고 더 효율적인 방법은 없을지 찾는 과정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>15684</category>
      <category>backtracking</category>
      <category>Baekjoon</category>
      <category>BruteForce</category>
      <category>implementation</category>
      <category>구현</category>
      <category>백준</category>
      <category>백트래킹</category>
      <category>브루트포스 알고리즘</category>
      <category>사다리 조작</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/442</guid>
      <comments>https://sound-programming.tistory.com/442#entry442comment</comments>
      <pubDate>Thu, 23 Jan 2025 21:01:57 +0900</pubDate>
    </item>
    <item>
      <title>코드트리 | HashMap / 순서를 바꾸었을 때 같은 단어 그룹화하기  {언어 : Python} [가장 작은 시공간복잡도]</title>
      <link>https://sound-programming.tistory.com/441</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-group-same-word/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.codetree.ai/trails/complete/curated-cards/challenge-group-same-word/description&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737100517801&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;Code Tree | Learning to Code with Confidence&quot; data-og-description=&quot;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&quot; data-og-host=&quot;www.codetree.ai&quot; data-og-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-group-same-word/description&quot; data-og-url=&quot;https://en.codetree.ai/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-group-same-word/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-group-same-word/description&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;Code Tree | Learning to Code with Confidence&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.codetree.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

n = int(input())
words = [input().strip() for _ in range(n)]

# Write your code here!
asciiDict = dict()
def makeKeys(word):
    tmpArr = [0] * 52 # 앞 26개는 대문자 뒤 26개는 소문자
    for w in word:
        ascii = ord(w)
        if ascii &amp;lt; 97:
            tmpArr[ascii-65] += 1
        else:
            tmpArr[ascii-71] += 1
    return &quot;&quot;.join(map(str, tmpArr))
for word in words:
    asciiKey = makeKeys(word)
    if asciiKey in asciiDict:
        asciiDict[asciiKey] += 1
    else:
        asciiDict[asciiKey] = 1
maxCnt = max(list(asciiDict.values()))
print(maxCnt)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ascii 코드를 활용해서 길이가 52인 문자열로 된 키를 만든다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;대문자는 65 ~ 90&lt;/li&gt;
&lt;li&gt;소문자는 97 ~ 122&lt;/li&gt;
&lt;li&gt;대문자는 앞에 0 ~ 25인덱스에 저장&lt;/li&gt;
&lt;li&gt;소문자는 뒤에 26 ~ 51인덱스에 저장&lt;/li&gt;
&lt;li&gt;&quot;AZABacaz&quot;라면&lt;/li&gt;
&lt;li&gt;[2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]&lt;/li&gt;
&lt;li&gt;이를 하나로 합치기 전에 map을 사용해서 문자로 바꾼다.&lt;/li&gt;
&lt;li&gt;join으로 합쳐서 ascii 키를 만든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;키를 asciiDict에 저장한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;있으면 +1&lt;/li&gt;
&lt;li&gt;없으면 1&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;values 중에 가장 큰 값을 max로 찾는다.&lt;/li&gt;
&lt;li&gt;maxCnt를 출력하면 끝!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;87&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xnJwE/btsLSm95Z0v/6gd15AkWVjQEUz6ryBL0V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xnJwE/btsLSm95Z0v/6gd15AkWVjQEUz6ryBL0V1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xnJwE/btsLSm95Z0v/6gd15AkWVjQEUz6ryBL0V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxnJwE%2FbtsLSm95Z0v%2F6gd15AkWVjQEUz6ryBL0V1%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;781&quot; height=&quot;87&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;87&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;li&gt;이유로는 문자열의 길이가 1000이라고 가정할 때 정렬해서 join하는 것 보다 길이가 52인 배열에 저장해서 join하는 것이 더 빠르기 때문이다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;이처럼 하나의 방법에 매몰되지 말고 여러 방법을 떠올리는 것이 중요하다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>ASCII</category>
      <category>CHR</category>
      <category>codetree</category>
      <category>HashMap</category>
      <category>ORD</category>
      <category>Python</category>
      <category>순서를 바꾸었을 때 같은 단어 그룹화하기</category>
      <category>아스키 코드</category>
      <category>코드트리</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/441</guid>
      <comments>https://sound-programming.tistory.com/441#entry441comment</comments>
      <pubDate>Fri, 17 Jan 2025 17:09:07 +0900</pubDate>
    </item>
    <item>
      <title>코드트리 | HashMAP / 원소의 합이 0  {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/440</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-the-sum-of-the-elements-is-0/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.codetree.ai/trails/complete/curated-cards/challenge-the-sum-of-the-elements-is-0/description&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737004372498&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;Code Tree | Learning to Code with Confidence&quot; data-og-description=&quot;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&quot; data-og-host=&quot;www.codetree.ai&quot; data-og-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-the-sum-of-the-elements-is-0/description&quot; data-og-url=&quot;https://en.codetree.ai/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qj4Je/hyX0tcsiM8/Hvs5ESBjFXGkjgfNEZ5DEK/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400,https://scrap.kakaocdn.net/dn/bASFZc/hyX4otLrDO/fnY1Es6ya78NS1N0AdYBlK/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-the-sum-of-the-elements-is-0/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-the-sum-of-the-elements-is-0/description&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qj4Je/hyX0tcsiM8/Hvs5ESBjFXGkjgfNEZ5DEK/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400,https://scrap.kakaocdn.net/dn/bASFZc/hyX4otLrDO/fnY1Es6ya78NS1N0AdYBlK/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400');&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;Code Tree | Learning to Code with Confidence&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.codetree.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))
D = list(map(int, input().split()))

# Write your code here!
answer = 0
dictAB = dict()
dictCD = dict()

def addKey(dictTmp, left, right):
    for i in range(n):
        elemL = left[i]
        for j in range(n):
            elemR = right[j]
            tmp = elemL + elemR
            if dictTmp.get(tmp, 0):
                dictTmp[tmp] += 1
            else:
                dictTmp[tmp] = 1

addKey(dictAB, A, B)
addKey(dictCD, C, D)
keysAB = list(dictAB.keys())
for kab in keysAB:
    kcd = 0 - kab
    if dictCD.get(kcd, 0):
        answer += dictAB[kab] * dictCD[kcd]

print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A1zut/btsLO7zgYCl/ppFKFknj4YCMj8ExDawXL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A1zut/btsLO7zgYCl/ppFKFknj4YCMj8ExDawXL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A1zut/btsLO7zgYCl/ppFKFknj4YCMj8ExDawXL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA1zut%2FbtsLO7zgYCl%2FppFKFknj4YCMj8ExDawXL0%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;795&quot; height=&quot;45&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;더 효율적인 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1737004342491&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n = int(input())
A = list(map(int,input().split()))
B = list(map(int,input().split()))
C = list(map(int,input().split()))
D = list(map(int,input().split()))

count = dict()
for i in range(n):
    for j in range(n):
        sum = A[i] + B[j]
        if sum in count:
            count[sum] += 1
        else:
            count[sum] = 1

result = 0
for i in range(n):
    for j in range(n):
        target = -(C[i] + D[j])
        if target in count:
            result += count[target]

print(result)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;A와 B에서 합을 키로 하고 빈도를 값으로 하는 딕셔너리를 만든다.&lt;/li&gt;
&lt;li&gt;C와 D에서 합을 키로 하고 빈도를 값으로 하는 딕셔너리를 만든다.&lt;/li&gt;
&lt;li&gt;둘의 키를 합쳤을 때 0이 되는 경우 answer에 각 값을 곱해서 더해준다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예를 들어 AB의 키가 45고 CD의 키가 -45인 경우&lt;/li&gt;
&lt;li&gt;answer += dictAB[45] * dictCD[-45]&lt;/li&gt;
&lt;li&gt;주의할 점
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;dictAB의 키의 개수는 1 &amp;lt;= 키의 개수 &amp;lt;= 5000 * 5000이 된다.&lt;/li&gt;
&lt;li&gt;따라서 이중 반복문으로 dictCD에 있는 키 값을 찾으면 안된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;즉 dictCD에 0 - kab가 존재하는지만 확인하면 되므로 이중 반복문을 사용하지 않아도 된다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;answer를 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;keys값의 개수가 5000개라고 생각해서 2중 for문을 사용한 결과 시간초과가 발생했다.&lt;/li&gt;
&lt;li&gt;더 효율적인 코드의 경우 두 번째 CD의 합을 구할 때 바로 0이 되는 경우의 수를 구해준다.&lt;/li&gt;
&lt;li&gt;따라서 반복을 한 번 더 할 필요가 없기 때문에 효율적인 코드가 된다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>codetree</category>
      <category>dict</category>
      <category>HashMap</category>
      <category>Python</category>
      <category>원소의 합이 0</category>
      <category>코드트리</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/440</guid>
      <comments>https://sound-programming.tistory.com/440#entry440comment</comments>
      <pubDate>Thu, 16 Jan 2025 14:20:24 +0900</pubDate>
    </item>
    <item>
      <title>코드트리 | HashMap / 자주 등장한 top k 숫자 {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/439</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-top-k-frequent-elements/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.codetree.ai/trails/complete/curated-cards/challenge-top-k-frequent-elements/description&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1736930279170&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;Code Tree | Learning to Code with Confidence&quot; data-og-description=&quot;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&quot; data-og-host=&quot;www.codetree.ai&quot; data-og-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-top-k-frequent-elements/description&quot; data-og-url=&quot;https://en.codetree.ai/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYAhc3/hyX0w09S4I/Wy8QYomqPksOix2LIUPbGk/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400,https://scrap.kakaocdn.net/dn/boiE22/hyX4xYqobS/rawofOcIxg3bpSoNKU7x7k/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-top-k-frequent-elements/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-top-k-frequent-elements/description&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYAhc3/hyX0w09S4I/Wy8QYomqPksOix2LIUPbGk/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400,https://scrap.kakaocdn.net/dn/boiE22/hyX4xYqobS/rawofOcIxg3bpSoNKU7x7k/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400');&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;Code Tree | Learning to Code with Confidence&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.codetree.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k = map(int, input().split())
arr = list(map(int, input().split()))

# Write your code here!
stack = []
dictArr = dict()
for num in arr:
    if dictArr.get(num, 0):
        dictArr[num] += 1
    else:
        dictArr[num] = 1
itemsArr = sorted(list(dictArr.items()), key=lambda x:(x[1], x[0]), reverse=True)
for i in range(k):
    iak, iav = itemsArr[i]
    print(iak, end=&quot; &quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A3vbk/btsLPmbksjy/Py0ZKXUl0aasTEv4q182Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A3vbk/btsLPmbksjy/Py0ZKXUl0aasTEv4q182Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A3vbk/btsLPmbksjy/Py0ZKXUl0aasTEv4q182Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA3vbk%2FbtsLPmbksjy%2FPy0ZKXUl0aasTEv4q182Kk%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;790&quot; height=&quot;52&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;다른 사람 풀이&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1736930540966&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k =map(int, input().split())
arr = list(map(int, input().split()))
freq = dict()

for num in arr:
    if num in freq:
        freq[num]+=1
        
    else:
        freq[num]=1

topk=dict()

keys = []
for key, value in freq.items():
    if value in topk:
        topk[value].append(key)
    else:
        topk[value] = [key]
        keys.append(value)

keys = sorted(keys, reverse=True)

for key, value in topk.items():
    topk[key] = sorted(topk[key],reverse=True)

for num in keys:
    if k&amp;lt;=0:
        break
    for answer in topk[num]:
        if k&amp;lt;=0:
            break

        print(answer, end=&quot; &quot;)
        k-=1&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&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;입력 받기&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;n, k는 숫자의 개수와 출력할 숫자의 개수.&lt;/li&gt;
&lt;li&gt;arr는 숫자가 담긴 배열.&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;freq 딕셔너리를 만들어 배열 arr의 각 숫자가 몇 번 등장했는지 저장한다.&lt;/li&gt;
&lt;li&gt;딕셔너리의 key는 숫자, value는 등장 횟수.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;빈도를 기준으로 그룹화&lt;/b&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;topk 딕셔너리를 만들어, 등장 횟수를 기준으로 숫자를 그룹화한다.&lt;/li&gt;
&lt;li&gt;딕셔너리의 key는 등장 횟수, value는 해당 등장 횟수를 가진 숫자의 리스트.&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;등장 횟수를 나타내는 key 값들을 keys 리스트에 모아, 내림차순으로 정렬한다.&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;등장 횟수가 높은 숫자부터 k개를 차례대로 출력한다.&lt;/li&gt;
&lt;li&gt;k가 0이 되면 반복을 멈춘다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속도가 283ms 와 96ms로 차이가 날 정도로 아래 코드가 더 효율적이다.&lt;/li&gt;
&lt;li&gt;lambda 오랜만에 써서 어떻게 쓰나 했다.&lt;/li&gt;
&lt;li&gt;sorted에 정렬을 하기 위해 key=을 사용해야 한다.&lt;/li&gt;
&lt;li&gt;다 까먹었다...&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘</category>
      <category>codetree</category>
      <category>dictionary</category>
      <category>HASH</category>
      <category>HashMap</category>
      <category>lambda</category>
      <category>Python</category>
      <category>Sorted</category>
      <category>자주 등장한 top k 숫자</category>
      <category>코드트리</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/439</guid>
      <comments>https://sound-programming.tistory.com/439#entry439comment</comments>
      <pubDate>Wed, 15 Jan 2025 17:49:14 +0900</pubDate>
    </item>
    <item>
      <title>코드트리 | HashMap / 세 수의 합  {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/438</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-sum-of-three-num/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.codetree.ai/trails/complete/curated-cards/challenge-sum-of-three-num/description&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1736863952002&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;Code Tree | Learning to Code with Confidence&quot; data-og-description=&quot;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&quot; data-og-host=&quot;www.codetree.ai&quot; data-og-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-sum-of-three-num/description&quot; data-og-url=&quot;https://en.codetree.ai/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bldTlC/hyX0lLXP53/vhhOxg4fWoQqv5WhZ6ySP0/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400,https://scrap.kakaocdn.net/dn/SR65C/hyX0pniK1U/xU2k8g830Ys9kqlyFlcLFK/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-sum-of-three-num/description&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.codetree.ai/trails/complete/curated-cards/challenge-sum-of-three-num/description&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bldTlC/hyX0lLXP53/vhhOxg4fWoQqv5WhZ6ySP0/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400,https://scrap.kakaocdn.net/dn/SR65C/hyX0pniK1U/xU2k8g830Ys9kqlyFlcLFK/img.png?width=1400&amp;amp;height=1400&amp;amp;face=0_0_1400_1400');&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;Code Tree | Learning to Code with Confidence&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A super-comprehensive, meticulously arranged Coding Learning Curriculum engineered by Algorithm Experts composed of former International Olympiad in Informatics (IOI) medalists.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.codetree.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1736863891429&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k = map(int, input().split())
arr = list(map(int, input().split()))

# Write your code here!
dictNum = dict()
for num in arr:
    if dictNum.get(num, 0):
        dictNum[num] += 1
    else:
        dictNum[num] = 1

answer = 0
keysNum = list(dictNum.keys())
visited = dict()
def makeKeys(a, b, c):
    return [str(a)+str(b)+str(c), 
            str(a)+str(c)+str(b), 
            str(b)+str(a)+str(c),
            str(b)+str(c)+str(a),
            str(c)+str(a)+str(b),
            str(c)+str(b)+str(a)]
lenN = len(keysNum)
for i in range(lenN):
    for j in range(lenN):
        a, b = keysNum[i], keysNum[j]
        c = k - (a + b)
        cntA = dictNum[a]
        cntB = dictNum[b]
        tmp = 0
        if dictNum.get(c, 0):
            cntC = dictNum[c]
            if a == b == c:
                tmp += (cntA * (cntA - 1) * (cntA - 2)) // 6
            elif a == b:
                tmp += ((cntA * (cntA - 1)) // 2) * cntC
            elif a == c:
                tmp += ((cntA * (cntA - 1)) // 2) * cntB
            elif b == c:
                tmp += ((cntB * (cntB - 1)) // 2) * cntA
            else:
                tmp += cntA * cntB * cntC
            vk = makeKeys(a, b, c)
            if not visited.get(vk[0], 0):
                for nk in vk:
                    visited[nk] = 1
                answer += tmp
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;p 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;792&quot; data-origin-height=&quot;47&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYCMMi/btsLOsh6i9D/OEcP4hkj0POzn91mKpJgtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYCMMi/btsLOsh6i9D/OEcP4hkj0POzn91mKpJgtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYCMMi/btsLOsh6i9D/OEcP4hkj0POzn91mKpJgtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYCMMi%2FbtsLOsh6i9D%2FOEcP4hkj0POzn91mKpJgtk%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;792&quot; height=&quot;47&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;47&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k = tuple(map(int, input().split()))
arr = list(map(int, input().split()))

count = dict()

for elem in arr:
    if elem in count:
        count[elem] += 1
    else:
        count[elem] = 1

ans = 0
for i in range(n):
    count[arr[i]] -= 1

    for j in range(i):
        diff = k - arr[i] - arr[j]

        if diff in count:
            ans += count[diff]

print(ans)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;: 배열 내 각 숫자의 빈도를 count 딕셔너리에 저장.&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;첫 번째 숫자(arr[i])를 선택 후, 중복 방지를 위해 빈도 감소.&lt;/li&gt;
&lt;li&gt;두 번째 숫자(arr[j])를 선택 후, k - arr[i] - arr[j]로 세 번째 숫자(diff) 계산.&lt;/li&gt;
&lt;li&gt;count에서 diff 존재 여부를 확인하고, 존재하면 빈도만큼 결과 증가.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결과 출력&lt;/b&gt;: 가능한 모든 조합의 경우의 수를 ans에 저장하고 출력.&lt;/li&gt;
&lt;/ol&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;느낀점&lt;/b&gt;&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;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>codetree</category>
      <category>dict</category>
      <category>dictionary</category>
      <category>HashMap</category>
      <category>Python</category>
      <category>세 수의 합</category>
      <category>코드트리</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/438</guid>
      <comments>https://sound-programming.tistory.com/438#entry438comment</comments>
      <pubDate>Tue, 14 Jan 2025 23:17:44 +0900</pubDate>
    </item>
    <item>
      <title>코드트리 | Two Pointer / 가장 짧은 부분합  {언어 : Python} [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/437</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/missions/8/problems/shortest-subtotal/submissions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.codetree.ai/missions/8/problems/shortest-subtotal/submissions&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735626494748&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;국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.&quot; data-og-host=&quot;www.codetree.ai&quot; data-og-source-url=&quot;https://www.codetree.ai/missions/8/problems/shortest-subtotal/submissions&quot; data-og-url=&quot;https://codetree.ai/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mKnzj/hyXWtvg8bh/SqeQskCu0jHqtfkDVkYkh0/img.png?width=3508&amp;amp;height=3508&amp;amp;face=0_0_3508_3508&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/missions/8/problems/shortest-subtotal/submissions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.codetree.ai/missions/8/problems/shortest-subtotal/submissions&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mKnzj/hyXWtvg8bh/SqeQskCu0jHqtfkDVkYkh0/img.png?width=3508&amp;amp;height=3508&amp;amp;face=0_0_3508_3508');&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;국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.codetree.ai&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;내 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707834183216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;n, k = map(int, input().split())
nums = list(map(int, input().split()))
tot = nums[0]
answer = 100000
r = 0
for l in range(n):
    while r + 1 &amp;lt; n and tot &amp;lt; k:
        tot += nums[r+1]
        r += 1
    if tot &amp;gt;= k:
        answer = min(answer, r - l + 1)
    tot -= nums[l]
if answer == 100000:
    print(-1)
else:
    print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&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;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; l과 끝 지점을 가리키는 &lt;b&gt;오른쪽 포인터&lt;/b&gt; r을 설정한다.&lt;/li&gt;
&lt;li&gt;처음에는 두 포인터가 배열의 첫 번째 원소를 가리킨다.&lt;/li&gt;
&lt;li&gt;현재 부분 배열의 합을 저장하는 변수 tot를 초기화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;오른쪽 포인터 이동 (확장)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 부분 배열의 합 tot이 목표값 k보다 작으면, &lt;b&gt;오른쪽 포인터&lt;/b&gt;를 이동시켜 배열의 다음 원소를 포함한다.&lt;/li&gt;
&lt;li&gt;새로운 원소를 tot에 추가하여 현재 합을 갱신한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;조건 만족 시 최소 길이 계산
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부분 배열의 합 tot이 k 이상이 되면, 현재 부분 배열의 길이를 계산한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;길이는 (오른쪽 포인터 - 왼쪽 포인터 + 1)로 구한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;계산한 길이를 기존의 최소 길이와 비교하여 더 짧은 값을 갱신한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;이때, 시작점이 빠지므로 tot에서 해당 값을 빼서 갱신한다.&lt;/li&gt;
&lt;li&gt;이렇게 하면 &lt;b&gt;부분 배열의 길이를 줄이면서도 조건을 만족하는지 확인&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;li&gt;결과 출력
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 k 이상의 합을 가지는 부분 배열이 한 번도 없다면, 결과로 -1을 출력한다.&lt;/li&gt;
&lt;li&gt;그렇지 않다면, 최소 길이를 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xTuZ1/btsLAU8CrXv/JEMJ0OKkNdaCPM30wLlBbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xTuZ1/btsLAU8CrXv/JEMJ0OKkNdaCPM30wLlBbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xTuZ1/btsLAU8CrXv/JEMJ0OKkNdaCPM30wLlBbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxTuZ1%2FbtsLAU8CrXv%2FJEMJ0OKkNdaCPM30wLlBbK%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;900&quot; height=&quot;141&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;작동 예제&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;예제 배열&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열: [5, 1, 3, 5, 10, 7, 4, 9, 2, 8]&lt;/li&gt;
&lt;li&gt;목표값: k = 15&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;과정&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;초기 상태: tot = 5, l = 0, r = 0.&lt;/li&gt;
&lt;li&gt;오른쪽 포인터 이동: tot = 5 + 1 + 3 + 5 = 14, 조건 미충족.&lt;/li&gt;
&lt;li&gt;계속 이동: tot = 14 + 10 = 24, 조건 충족 &amp;rarr; 길이 계산 &amp;rarr; 최소 길이 = 5.&lt;/li&gt;
&lt;li&gt;왼쪽 포인터 이동: tot = 24 - 5 = 19, 조건 충족 &amp;rarr; 길이 갱신 &amp;rarr; 최소 길이 = 4.&lt;/li&gt;
&lt;li&gt;반복: 최단 길이 = 2까지 갱신.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조건을 만족하는 부분 배열의 최소 길이: 2.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/다시 풀어 보기</category>
      <category>codetree</category>
      <category>Python</category>
      <category>Two Pointer</category>
      <category>가장 짧은 부분합</category>
      <category>코드트리</category>
      <category>투 포인터</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/437</guid>
      <comments>https://sound-programming.tistory.com/437#entry437comment</comments>
      <pubDate>Tue, 31 Dec 2024 16:40:08 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-DATE] 프로그래머스 Lv. 3 오랜 기간 보호한 동물(2)</title>
      <link>https://sound-programming.tistory.com/435</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/59411&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/59411&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735277884825&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/59411&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jsiIH/hyXSyEdljP/S9krJ1Xocnrm2SEMcLdKwk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/kmfFj/hyXSCmiEfl/9C9doUXqGS1wS5ycRNbI3k/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/59411&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59411&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jsiIH/hyXSyEdljP/S9krJ1Xocnrm2SEMcLdKwk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/kmfFj/hyXSCmiEfl/9C9doUXqGS1wS5ycRNbI3k/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    ANMO.ANIMAL_ID,
    ANMO.NAME
FROM ANIMAL_INS ANMI
RIGHT JOIN ANIMAL_OUTS ANMO
ON ANMI.ANIMAL_ID = ANMO.ANIMAL_ID 
    AND ANMI.DATETIME IS NOT NULL
ORDER BY DATEDIFF(ANMO.DATETIME, ANMI.DATETIME) DESC
LIMIT 2;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&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;조인 조건&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 ANIMAL_ID를 기준으로 &lt;b&gt;RIGHT JOIN&lt;/b&gt;한다.&lt;/li&gt;
&lt;li&gt;조인 조건에 추가로 ANMI.DATETIME IS NOT NULL이 적용되어, ANIMAL_INS의 DATETIME이 NULL이 아닌 경우만 포함된다.&lt;/li&gt;
&lt;li&gt;RIGHT JOIN을 사용했기 때문에 ANIMAL_OUTS에 있는 모든 동물이 결과에 포함되며, ANIMAL_INS에 없는 동물도 조회될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SELECT&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조인된 결과에서 ANIMAL_OUTS의 ANIMAL_ID와 NAME 컬럼을 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DATEDIFF 계산 및 정렬&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DATEDIFF(ANMO.DATETIME, ANMI.DATETIME)를 계산하여 동물이 입소된 날짜(ANMI.DATETIME)와 출소된 날짜(ANMO.DATETIME) 간의 차이를 기준으로 정렬한다.&lt;/li&gt;
&lt;li&gt;DESC 정렬을 사용하여 날짜 차이가 가장 큰 동물이 우선으로 출력된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LIMIT&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정렬된 결과에서 상위 2개만 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문법에 대해서 많이 떠오르지는 않지만 LIMIT, JOIN, ORDER BY를 적절하게 사용해서 문제를 풀어 봤다.&lt;/li&gt;
&lt;li&gt;다음 게시글에는 내장함수를 정리하고 다시 풀어 봐야 하는 문제들을 복습할 것 같다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/String, Date</category>
      <category>date</category>
      <category>is not null</category>
      <category>level 3</category>
      <category>Limit</category>
      <category>programmers</category>
      <category>right join</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>오랜 기간 보호한 동물(2)</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/435</guid>
      <comments>https://sound-programming.tistory.com/435#entry435comment</comments>
      <pubDate>Fri, 27 Dec 2024 14:40:33 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-STRING] 프로그래머스 Lv. 3 조건에 맞는 사용자 정보 조회하기 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/434</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/164670&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/164670&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735276815258&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/164670&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGgaHS/hyXStCUqKF/s9EMSll3vPMHZItn0cJOt0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/tHo5t/hyXSwM97kp/xCUspLyN6vaAGn3GJsakbk/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/164670&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/164670&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGgaHS/hyXStCUqKF/s9EMSll3vPMHZItn0cJOt0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/tHo5t/hyXSwM97kp/xCUspLyN6vaAGn3GJsakbk/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH THREE_MORE AS (
    SELECT WRITER_ID
    FROM USED_GOODS_BOARD
    GROUP BY WRITER_ID
    HAVING COUNT(*) &amp;gt;= 3
),
TM_USERS AS (
    SELECT
        UGU.USER_ID,
        UGU.NICKNAME,
        CONCAT(UGU.CITY, ' ', UGU.STREET_ADDRESS1, ' ', UGU.STREET_ADDRESS2) AS 전체주소,
        CONCAT(SUBSTRING(UGU.TLNO, 1, 3), '-', SUBSTRING(UGU.TLNO, 4, 4), '-', SUBSTRING(UGU.TLNO, 8, 4)) AS 전화번호
    FROM THREE_MORE TM
    JOIN USED_GOODS_USER UGU
    ON TM.WRITER_ID = UGU.USER_ID
)
SELECT * FROM TM_USERS ORDER BY USER_ID DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이 SQL 쿼리는 게시글을 3개 이상 작성한 사용자의 정보를 조회하고 정렬한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 번째 CTE THREE_MORE는 USED_GOODS_BOARD 테이블에서 작성자 ID(WRITER_ID)를 기준으로 그룹화하고, HAVING COUNT(*) &amp;gt;= 3 조건을 사용하여 게시글 개수가 3개 이상인 작성자만 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;두 번째 CTE TM_USERS는 첫 번째 CTE의 결과와 USED_GOODS_USER 테이블을 조인하여 사용자 정보를 조회한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조인 조건은 THREE_MORE.WRITER_ID = USED_GOODS_USER.USER_ID다.&lt;/li&gt;
&lt;li&gt;전체 주소(전체주소)는 CITY, STREET_ADDRESS1, STREET_ADDRESS2를 CONCAT 함수로 연결해 생성된다.&lt;/li&gt;
&lt;li&gt;전화번호(전화번호)는 SUBSTRING과 CONCAT을 사용해 XXX-XXXX-XXXX 형식으로 변환된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최종적으로, TM_USERS에서 사용자 ID, 닉네임, 전체 주소, 전화번호를 선택하고 USER_ID를 기준으로 내림차순 정렬하여 출력한다.
&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;/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;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HAVING을 사용해서 3개 이상의 유저를 찾는 방법을 배웠다.&lt;/li&gt;
&lt;li&gt;SUBSTRING으로 자르는데 SUBSTRING('1234567', 2, 3)이면 INDEX 2번째 =&amp;gt; '2'부터 3개 =&amp;gt; '234'가 출력된다.&lt;/li&gt;
&lt;li&gt;여기서 주의할 점은 SUBSTRING의 맨 처음 INDEX는 1이다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/다시 풀어 보기</category>
      <category>group by</category>
      <category>HAVING</category>
      <category>level 3</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>string</category>
      <category>substring</category>
      <category>조건에 맞는 사용자 정보 조회하기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/434</guid>
      <comments>https://sound-programming.tistory.com/434#entry434comment</comments>
      <pubDate>Fri, 27 Dec 2024 14:30:40 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-STRING, DATE] 프로그래머스 Lv. 3 대여 기록이 존재하는 자동차 리스트 구하기</title>
      <link>https://sound-programming.tistory.com/433</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/157341&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/157341&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735275268072&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/157341&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hHH8F/hyXSrLQnVd/r43EMVNZRnZBoKHtEV2eNk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/YRFj2/hyXSpgaOIJ/lDm4kQSk7i0hDcoPhxBEJ0/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/157341&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/157341&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hHH8F/hyXSrLQnVd/r43EMVNZRnZBoKHtEV2eNk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/YRFj2/hyXSpgaOIJ/lDm4kQSk7i0hDcoPhxBEJ0/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CRCRH.CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY CRCRH
JOIN CAR_RENTAL_COMPANY_CAR CRCC
ON CRCRH.CAR_ID = CRCC.CAR_ID 
    AND CRCRH.START_DATE BETWEEN '2022-10-01' AND '2022-10-31' 
    AND CRCC.CAR_TYPE = '세단'
GROUP BY CRCRH.CAR_ID
ORDER BY CRCRH.CAR_ID DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;a1f2faa4-9b9f-4e53-844b-5203fa89a3c2&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;CAR_RENTAL_COMPANY_RENTAL_HISTORY (CRCRH)와 CAR_RENTAL_COMPANY_CAR (CRCC)를 CAR_ID를 기준으로 조인한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ON 조건을 만족하는 데이터만 결합되며, CRCRH.CAR_ID = CRCC.CAR_ID 조건이 적용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;조인된 데이터에서 WHERE 조건에 따라 필터링한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조건은 CRCRH.START_DATE가 2022-10-01에서 2022-10-31 사이에 포함되고, CRCC.CAR_TYPE이 '세단'인 경우다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;필터링된 데이터를 GROUP BY CRCRH.CAR_ID로 그룹화하여 중복된 차량 ID를 제거한다.&lt;/li&gt;
&lt;li&gt;그룹화된 데이터에서 SELECT 문을 통해 CAR_ID를 선택한다.&lt;/li&gt;
&lt;li&gt;마지막으로 ORDER BY CRCRH.CAR_ID DESC를 적용하여 차량 ID를 내림차순으로 정렬하고 결과를 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JOIN을 할 때 INNER JOIN으로 조건을 모두 만족하는 경우만 출력하게 했으며 CAR_ID를 그룹화 시켜서 중복을 제거했다.&lt;/li&gt;
&lt;li&gt;한번에 풀려서 다행이라고 느끼면서도 항상 실수하지 않도록 꼼꼼히 풀어 보자.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/String, Date</category>
      <category>Between</category>
      <category>date</category>
      <category>join</category>
      <category>level 3</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>string</category>
      <category>대여 기록이 존재하는 자동차 리스트 구하기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/433</guid>
      <comments>https://sound-programming.tistory.com/433#entry433comment</comments>
      <pubDate>Fri, 27 Dec 2024 13:58:23 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-DATE] 프로그래머스 Lv. 3 조건별로 분류하여 주문상태 출력하기 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/432</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/131113&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/131113&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735274583969&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/131113&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hhjkH/hyXSEYHUhX/f2EAbl0GQQ0NKN0ue5kSn0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/Oa7G9/hyXSzb1Do6/DvMMflqsIdAKl4AJg1DTXk/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/131113&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131113&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hhjkH/hyXSEYHUhX/f2EAbl0GQQ0NKN0ue5kSn0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/Oa7G9/hyXSzb1Do6/DvMMflqsIdAKl4AJg1DTXk/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    ORDER_ID,
    PRODUCT_ID,
    DATE_FORMAT(OUT_DATE, '%Y-%m-%d') AS OUT_DATE,
    CASE
        WHEN OUT_DATE &amp;gt; '2022-05-01' THEN '출고대기'
        WHEN OUT_DATE &amp;lt;= '2022-05-01' THEN '출고완료'
        ELSE '출고미정'
    END AS 출고여부
FROM FOOD_ORDER
ORDER BY ORDER_ID;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&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;컬럼 선택 및 변환&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;: ORDER_ID, PRODUCT_ID, OUT_DATE 정보를 가져오고, OUT_DATE는 지정된 형식(YYYY-MM-DD)으로 변환.&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;SELECT ORDER_ID, PRODUCT_ID, DATE_FORMAT(OUT_DATE, '%Y-%m-%d') AS OUT_DATE&lt;/li&gt;
&lt;li&gt;DATE_FORMAT 함수는 OUT_DATE를 원하는 날짜 형식으로 출력.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;&lt;b&gt;목적&lt;/b&gt;: OUT_DATE에 따라 출고 여부를 계산하여 새로운 컬럼(출고여부)을 생성.&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;CASE 문으로 조건을 설정:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;OUT_DATE &amp;gt; '2022-05-01': &lt;b&gt;출고대기&lt;/b&gt; (미래 날짜)&lt;/li&gt;
&lt;li&gt;OUT_DATE &amp;lt;= '2022-05-01': &lt;b&gt;출고완료&lt;/b&gt; (과거 또는 같은 날짜)&lt;/li&gt;
&lt;li&gt;ELSE: 기본값으로 &lt;b&gt;출고미정&lt;/b&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;결과는 출고여부 컬럼으로 출력.&lt;/li&gt;
&lt;/ul&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;목적&lt;/b&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;FROM FOOD_ORDER를 통해 &lt;b&gt;FOOD_ORDER&lt;/b&gt; 테이블에서 데이터를 가져온다.&lt;/li&gt;
&lt;/ul&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;목적&lt;/b&gt;: 결과를 ORDER_ID 기준으로 정렬.&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;ORDER BY ORDER_ID를 사용해 ORDER_ID의 오름차순으로 정렬한다.&lt;/li&gt;
&lt;/ul&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;목적&lt;/b&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;ORDER_ID: 주문 ID.&lt;/li&gt;
&lt;li&gt;PRODUCT_ID: 제품 ID.&lt;/li&gt;
&lt;li&gt;OUT_DATE: YYYY-MM-DD 형식의 출고 날짜.&lt;/li&gt;
&lt;li&gt;출고여부: 출고 상태를 나타냄.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DATE 부분도 실수하기 쉬운 부분 같다.&lt;/li&gt;
&lt;li&gt;%Y-%M-%D인지 %Y-%M인지 시간을 필요로 하는지를 유의해서 문제를 풀자.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/다시 풀어 보기</category>
      <category>Case</category>
      <category>date</category>
      <category>date_format</category>
      <category>level 3</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>조건별로 분류하여 주문상태 출력하기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/432</guid>
      <comments>https://sound-programming.tistory.com/432#entry432comment</comments>
      <pubDate>Fri, 27 Dec 2024 13:48:51 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-STRING] 프로그래머스 Lv. 3 조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/431</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/164671&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/164671&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735272866636&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/164671&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dOIP5T/hyXSuu1czd/hP2eNLtBuxpDhKzKiIE8J1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/AfiDE/hyXSCT6Ck9/qOoQ4DptI6j4p7nEgQzZt0/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/164671&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/164671&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dOIP5T/hyXSuu1czd/hP2eNLtBuxpDhKzKiIE8J1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/AfiDE/hyXSCT6Ck9/qOoQ4DptI6j4p7nEgQzZt0/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1735272853646&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH MAX_GOODS AS (
    SELECT BOARD_ID
    FROM USED_GOODS_BOARD
    ORDER BY VIEWS DESC
    LIMIT 1
), MAX_GOODS_FILE_PATH AS (
    SELECT '/home/grep/src/' + BOARD_ID + '/' + FILE_ID + FILE_EXT
    FROM USED_GOODS_FILE UGF
    JOIN MAX_GOODS MG
    ON MG.BOARD_ID = UGF.BOARD_ID
    ORDER BY UGF.FILE_ID DESC
)
SELECT * FROM MAX_GOODS_FILE_PATH;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 가장 조회수가 높은 게시물의 BOARD_ID를 가져오는 CTE
WITH MAX_GOODS AS (
    SELECT BOARD_ID
    FROM USED_GOODS_BOARD
    ORDER BY VIEWS DESC
    LIMIT 1
),
-- 해당 게시물의 파일 경로를 생성하는 CTE
MAX_GOODS_FILE_PATH AS (
    SELECT 
        CONCAT('/home/grep/src/', UGF.BOARD_ID, '/', UGF.FILE_ID, UGF.FILE_NAME, UGF.FILE_EXT) AS FILE_PATH
    FROM USED_GOODS_FILE UGF
    JOIN MAX_GOODS MG
    ON MG.BOARD_ID = UGF.BOARD_ID
    ORDER BY UGF.FILE_ID DESC
)
-- 최종 결과 출력
SELECT FILE_PATH
FROM MAX_GOODS_FILE_PATH;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&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;MAX_GOODS CTE 생성&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;: 조회수가 가장 높은 게시물의 BOARD_ID를 가진다.&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;USED_GOODS_BOARD 테이블에서 VIEWS 기준으로 내림차순 정렬.&lt;/li&gt;
&lt;li&gt;LIMIT 1을 사용하여 가장 조회수가 높은 게시물 하나만 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MAX_GOODS_FILE_PATH CTE 생성&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;: 조회수가 가장 높은 게시물과 연결된 파일들의 경로를 생성한다.&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;USED_GOODS_FILE 테이블과 MAX_GOODS를 조인하여 해당 게시물의 파일 정보 가져오기.&lt;/li&gt;
&lt;li&gt;CONCAT 함수로 파일 경로를 /home/grep/src/{BOARD_ID}/{FILE_ID}{FILE_NAME}{FILE_EXT} 형식으로 생성.&lt;/li&gt;
&lt;li&gt;FILE_ID를 기준으로 내림차순 정렬.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최종 SELECT&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;: 생성된 파일 경로 출력.&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;MAX_GOODS_FILE_PATH CTE에서 FILE_PATH 컬럼만 선택하여 결과로 반환.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CONCAT부분만 틀린줄 알았더니 FILE_PATH 부분이 잘 못된 것으로 보아 문제를 제대로 읽지 않았다는 것을 깨달았다.&lt;/li&gt;
&lt;li&gt;문제를 꼼꼼하게 보는 습관은 언제나 중요하다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/다시 풀어 보기</category>
      <category>concat</category>
      <category>join</category>
      <category>level 3</category>
      <category>MAX</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>string</category>
      <category>조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/431</guid>
      <comments>https://sound-programming.tistory.com/431#entry431comment</comments>
      <pubDate>Fri, 27 Dec 2024 13:23:05 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-JOIN] 프로그래머스 Lv. 3 오랜 기간 보호한 동물(1)</title>
      <link>https://sound-programming.tistory.com/430</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/59044&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/59044&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735201074965&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/59044&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/djJoAQ/hyXSpG0OhR/GhMt9GVTxa2rWwcTnELjBK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/dbLijA/hyXSvHePl4/mvMGE0sJWbRIOFUlVZFYk1/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/59044&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59044&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/djJoAQ/hyXSpG0OhR/GhMt9GVTxa2rWwcTnELjBK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/dbLijA/hyXSvHePl4/mvMGE0sJWbRIOFUlVZFYk1/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH STILL_STAY AS (
    SELECT
        ANI.NAME,
        ANI.DATETIME
    FROM ANIMAL_INS ANI
    LEFT JOIN ANIMAL_OUTS ANO
    ON ANI.ANIMAL_ID = ANO.ANIMAL_ID
    WHERE ANO.ANIMAL_ID IS NULL
)
SELECT * FROM STILL_STAY ORDER BY DATETIME LIMIT 3;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ANIMAL_INS와 ANIMAL_OUTS를 LEFT JOIN하여 &lt;b&gt;입양되지 않은 동물&lt;/b&gt;을 필터링.&lt;/li&gt;
&lt;li&gt;입양되지 않은 동물들의 이름과 입소 날짜를 가져옴.&lt;/li&gt;
&lt;li&gt;입소 날짜 기준으로 정렬하고 상위 3개만 출력.&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;b&gt;느낀점&lt;/b&gt;&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;/ul&gt;</description>
      <category>SQL/JOIN</category>
      <category>join</category>
      <category>Left Join</category>
      <category>level 3</category>
      <category>Limit</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>오랜 기간 보호한 동물(1)</category>
      <category>조인</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/430</guid>
      <comments>https://sound-programming.tistory.com/430#entry430comment</comments>
      <pubDate>Thu, 26 Dec 2024 17:19:19 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-JOIN] 프로그래머스 Lv. 3 있었는데요 없었습니다</title>
      <link>https://sound-programming.tistory.com/429</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/59043&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/59043&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735200411824&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/59043&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bFltrp/hyXSAPhFiy/krSuus0zIEhkqEZdVtqKnk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cYB9nF/hyXSpmHwjo/AkvVLhb1MwlYqmJ4hl6ft0/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/59043&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59043&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bFltrp/hyXSAPhFiy/krSuus0zIEhkqEZdVtqKnk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cYB9nF/hyXSpmHwjo/AkvVLhb1MwlYqmJ4hl6ft0/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
    ANI.ANIMAL_ID,
    ANI.NAME
FROM ANIMAL_INS ANI
JOIN ANIMAL_OUTS ANO
ON ANI.ANIMAL_ID = ANO.ANIMAL_ID AND ANI.DATETIME &amp;gt; ANO.DATETIME
ORDER BY ANI.DATETIME;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;ANIMAL_INS와 ANIMAL_OUTS를 ANIMAL_ID로 JOIN.&lt;/li&gt;
&lt;li&gt;ANI.DATETIME &amp;gt; ANO.DATETIME 조건으로 입양 날짜가 입소 날짜보다 앞선 데이터를 필터링.&lt;/li&gt;
&lt;li&gt;결과를 ANI.DATETIME 기준으로 정렬하여 출력.&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;b&gt;느낀점&lt;/b&gt;&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;/ul&gt;</description>
      <category>SQL/JOIN</category>
      <category>Inner Join</category>
      <category>join</category>
      <category>level 3</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>있었는데요 없었습니다</category>
      <category>조인</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/429</guid>
      <comments>https://sound-programming.tistory.com/429#entry429comment</comments>
      <pubDate>Thu, 26 Dec 2024 17:08:57 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-JOIN] 프로그래머스 Lv. 3 없어진 기록 찾기 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/428</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/59042&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/59042&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735199952511&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/59042&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wI9yq/hyXSrdKm16/Dtgp86wvbnvRYrCjaHCZIk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cMg7MH/hyXSyDXXid/WAgmO39aSxk09dYRrreSFK/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/59042&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59042&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wI9yq/hyXSrdKm16/Dtgp86wvbnvRYrCjaHCZIk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cMg7MH/hyXSyDXXid/WAgmO39aSxk09dYRrreSFK/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 
    ANO.ANIMAL_ID,
    ANO.NAME
FROM ANIMAL_OUTS ANO
LEFT JOIN ANIMAL_INS ANI
ON ANO.ANIMAL_ID = ANI.ANIMAL_ID
WHERE ANI.ANIMAL_ID IS NULL
ORDER BY ANO.ANIMAL_ID;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&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;LEFT JOIN&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ANIMAL_OUTS를 기준으로 ANIMAL_INS와 LEFT JOIN하여, ANIMAL_OUTS의 모든 데이터를 가져오고 ANIMAL_INS에 해당하는 데이터를 매칭.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;WHERE 조건&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ANI.ANIMAL_ID IS NULL 조건을 통해, ANIMAL_OUTS에는 있지만 ANIMAL_INS에는 없는 데이터(유실된 데이터)를 필터링.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ORDER BY&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ANIMAL_ID 기준으로 오름차순 정렬.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;INNER JOIN, OUTER JOIN, FULL JOIN에 대해서 더 알고 싶으면 아래 링크를 타고 들어가서 공부하면 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735200008673&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;SQL 기본 문법: JOIN(INNER, OUTER, CROSS, SELF JOIN)&quot; data-og-description=&quot;조인은 두 개의 테이블을 서로 묶어서 하나의 결과를 만들어 내는 것을 말한다. INNER JOIN(내부 조인)은 두 테이블을 조인할 때, 두 테이블에 모두 지정한 열의 데이터가 있어야 한다.OUTER JOIN(외부 &quot; data-og-host=&quot;hongong.hanbit.co.kr&quot; data-og-source-url=&quot;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&quot; data-og-url=&quot;https://hongong.hanbit.co.kr/sql-기본-문법-joininner-outer-cross-self-join/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btidXK/hyXSCl2JF8/QQLYyUHkfehvIGEAIbMns1/img.png?width=1080&amp;amp;height=1080&amp;amp;face=0_0_1080_1080,https://scrap.kakaocdn.net/dn/bCmtYB/hyXSun08TR/xjL07bVnuMg57nFBLWTNg1/img.png?width=1080&amp;amp;height=1080&amp;amp;face=0_0_1080_1080,https://scrap.kakaocdn.net/dn/fYqvi/hyXSCM7R8Y/roOpjwmbpuDDVKEPSGgs70/img.png?width=1080&amp;amp;height=1080&amp;amp;face=0_0_1080_1080&quot;&gt;&lt;a href=&quot;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btidXK/hyXSCl2JF8/QQLYyUHkfehvIGEAIbMns1/img.png?width=1080&amp;amp;height=1080&amp;amp;face=0_0_1080_1080,https://scrap.kakaocdn.net/dn/bCmtYB/hyXSun08TR/xjL07bVnuMg57nFBLWTNg1/img.png?width=1080&amp;amp;height=1080&amp;amp;face=0_0_1080_1080,https://scrap.kakaocdn.net/dn/fYqvi/hyXSCM7R8Y/roOpjwmbpuDDVKEPSGgs70/img.png?width=1080&amp;amp;height=1080&amp;amp;face=0_0_1080_1080');&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;SQL 기본 문법: JOIN(INNER, OUTER, CROSS, SELF JOIN)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;조인은 두 개의 테이블을 서로 묶어서 하나의 결과를 만들어 내는 것을 말한다. INNER JOIN(내부 조인)은 두 테이블을 조인할 때, 두 테이블에 모두 지정한 열의 데이터가 있어야 한다.OUTER JOIN(외부&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hongong.hanbit.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>SQL/다시 풀어 보기</category>
      <category>is null</category>
      <category>join</category>
      <category>Left Join</category>
      <category>level 3</category>
      <category>NULL</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>없어진 기록 찾기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/428</guid>
      <comments>https://sound-programming.tistory.com/428#entry428comment</comments>
      <pubDate>Thu, 26 Dec 2024 17:00:56 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-IS NULL] 프로그래머스 Lv. 3 업그레이드 할 수 없는 아이템 구하기 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/427</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/273712&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/273712&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1735199145099&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/273712&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/AUtUy/hyXSwlPkfM/9fYYN4OSzS64EoXcoJ1NgK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/caw5F3/hyXSq6YFXB/FuSQmdzUpRFTwPDRWLHONK/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/273712&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/273712&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/AUtUy/hyXSwlPkfM/9fYYN4OSzS64EoXcoJ1NgK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/caw5F3/hyXSq6YFXB/FuSQmdzUpRFTwPDRWLHONK/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1735199100483&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH HAVE_PAR AS (
    SELECT PARENT_ITEM_ID
    FROM ITEM_TREE
    WHERE PARENT_ITEM_ID IS NOT NULL
    GROUP BY PARENT_ITEM_ID
), NO_UPGRADE AS (
    SELECT
        II.ITEM_ID,
        II.ITEM_NAME,
        II.RARITY
    FROM ITEM_INFO II
    JOIN HAVE_PAR HP
    ON HP.PARENT_ITEM_ID != II.ITEM_ID
)
SELECT
    ITEM_ID,
    ITEM_NAME,
    RARITY
FROM NO_UPGRADE
ORDER BY ITEM_ID DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH NO_UPGRADE AS (
    SELECT 
        II.ITEM_ID,
        II.ITEM_NAME,
        II.RARITY
    FROM ITEM_INFO II
    LEFT JOIN ITEM_TREE IT
    ON II.ITEM_ID = IT.PARENT_ITEM_ID
    WHERE IT.PARENT_ITEM_ID IS NULL
)
SELECT
    ITEM_ID,
    ITEM_NAME,
    RARITY
FROM NO_UPGRADE
ORDER BY ITEM_ID DESC;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;NO_UPGRADE CTE:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ITEM_INFO 테이블을 기준으로 ITEM_TREE 테이블과 LEFT JOIN.&lt;/li&gt;
&lt;li&gt;ITEM_TREE.PARENT_ITEM_ID IS NULL 조건을 사용하여 더 이상 업그레이드 대상이 아닌 아이템을 필터링.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최종 SELECT:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NO_UPGRADE CTE에서 필요한 컬럼 (ITEM_ID, ITEM_NAME, RARITY)을 선택.&lt;/li&gt;
&lt;li&gt;ORDER BY ITEM_ID DESC로 아이템 ID 기준 내림차순 정렬.&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;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LEFT JOIN을 하면 빈 값은 NULL로 채워지며 NULL인 값을 찾으면 업그레이드가 불가능한 아이템이 된다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/다시 풀어 보기</category>
      <category>is null</category>
      <category>join</category>
      <category>Left Join</category>
      <category>level 3</category>
      <category>NULL</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>업그레이드 할 수 없는 아이템 구하기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/427</guid>
      <comments>https://sound-programming.tistory.com/427#entry427comment</comments>
      <pubDate>Thu, 26 Dec 2024 16:47:19 +0900</pubDate>
    </item>
    <item>
      <title>백준 GOLD 4 [1504번] 특정한 최단 경로  {언어 : Python}</title>
      <link>https://sound-programming.tistory.com/426</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1504&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://www.acmicpc.net/problem/1504&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import sys
import heapq

input = sys.stdin.readline
n, e = map(int, input().split())
adjL = [[] for _ in range(n+1)]
for _ in range(e):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start, to, dist = map(int, input().split())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjL[start].append([to, dist])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adjL[to].append([start, dist])
v1, v2 = map(int, input().split())
# 1에서 v1 까지 최소 + N에서 v2 까지 최소 + v1 v2 까지 최소
# 1에서 v2 까지 최소 + N에서 v1 까지 최소 + v1 v2 까지 최소
def Dijkstra(s1, t1):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dp = [-1] * (n+1) # 최단 경로로 해야하므로
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hq = [[0, s1]]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while hq:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dist, start = heapq.heappop(hq)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for to, nd in adjL[start]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newD = dist + nd
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if dp[to] == -1 or dp[to] &amp;gt; newD:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dp[to] = newD
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;heapq.heappush(hq, [newD, to])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return dp[t1]

oneToV1 = Dijkstra(1, v1)
oneToV2 = Dijkstra(1, v2)
v1ToV2 = Dijkstra(v1, v2)
nToV1 = Dijkstra(n, v1)
nToV2 = Dijkstra(n, v2)

ov1v2n = -1
ov2v1n = -1
if v1ToV2 &amp;gt;= 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if v1 == 1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if v2 == n:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ov1v2n = ov2v1n = v1ToV2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if nToV2 &amp;gt;= 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ov1v2n = v1ToV2 + nToV2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if oneToV1 &amp;gt;= 0 and nToV2 &amp;gt;= 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ov1v2n = oneToV1 + v1ToV2 + nToV2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if oneToV2 &amp;gt;= 0 and nToV1 &amp;gt;= 0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ov2v1n = oneToV2 + v1ToV2 + nToV1

if ov1v2n == -1 and ov2v1n == -1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(-1)
else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if ov1v2n == -1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ov1v2n = 800_001
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if ov2v1n == -1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ov2v1n = 800_001
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(min(ov1v2n, ov2v1n))&lt;/code&gt;&lt;/pre&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 방법&lt;/b&gt;&lt;/h3&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;&lt;li&gt;1에서 v1까지 v1에서 v2까지 v2에서 n까지 거리를 구한다.&lt;/li&gt;&lt;li&gt;1에서 v2까지 v2에서 v1까지 v1에서 n까지 거리를 구한다.&lt;/li&gt;&lt;li&gt;각각의 거리에서 -1이 나오면 안되므로 검증한다.&lt;/li&gt;&lt;li&gt;v1이 1일 때와 v2가 n일때를 구분한다.&lt;/li&gt;&lt;li&gt;마지막으로 ov1v2n과 ov2v1n이 모두 -1일 때는 길이 없으므로 -1&lt;/li&gt;&lt;li&gt;아닌 경우에는 -1인 쪽을 800_001로 치환하고 최소 값을 출력하면 끝!&lt;/li&gt;&lt;/ol&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1431&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z85Lr/btsLtfpNRKJ/JZtGvQVKh7bPvFwzxkADKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z85Lr/btsLtfpNRKJ/JZtGvQVKh7bPvFwzxkADKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z85Lr/btsLtfpNRKJ/JZtGvQVKh7bPvFwzxkADKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ85Lr%2FbtsLtfpNRKJ%2FJZtGvQVKh7bPvFwzxkADKK%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;1431&quot; height=&quot;272&quot; data-origin-width=&quot;1431&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주의 사항&lt;/b&gt;&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;v1이 1이 아니라는 보장이 없고&lt;/li&gt;&lt;li&gt;v2가 n이 아니라는 보장이 없다.&lt;/li&gt;&lt;li&gt;대신 v1은 n이 아니라는 조건과 v2는 1이 아니라는 조건은 있었다.&lt;/li&gt;&lt;/ul&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&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;/ul&gt;</description>
      <category>알고리즘/풀었지만 다시 보기</category>
      <category>Baekjoon</category>
      <category>Python</category>
      <category>골드 4</category>
      <category>그래프 이론</category>
      <category>데이크스트라</category>
      <category>동적계획법</category>
      <category>백준</category>
      <category>최단 경로</category>
      <category>특정한 최단 경로</category>
      <category>파이썬</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/426</guid>
      <comments>https://sound-programming.tistory.com/426#entry426comment</comments>
      <pubDate>Tue, 24 Dec 2024 15:36:11 +0900</pubDate>
    </item>
    <item>
      <title>[SQL-GROUP BY] 프로그래머스 Lv. 3 특정 조건을 만족하는 물고기별 수와 최대 길이 구하기 [다시 풀어 보기]</title>
      <link>https://sound-programming.tistory.com/425</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 링크&lt;/b&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/298519&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/298519&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1734952968649&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/298519&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eGoyv/hyXOg5yqp5/Y8c0Yp2Uq9rX6qjoGkGF80/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/ujuMu/hyXSz3rGgh/mzdcUdtPPf167k0w3vPqs0/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/298519&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/298519&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eGoyv/hyXOg5yqp5/Y8c0Yp2Uq9rX6qjoGkGF80/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/ujuMu/hyXSz3rGgh/mzdcUdtPPf167k0w3vPqs0/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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;틀린 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1734953035906&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH FISH_TOTAL_AVG AS (
    SELECT
        AVG(LENGTH) AS TOTAL_AVG
    FROM FISH_INFO
), FISH_TYPE_AVG AS (
    SELECT
        ID,
        FISH_TYPE,
        AVG(LENGTH) AS TYPE_AVG,
        MAX(LENGTH) AS MAX_LENGTH,
        COUNT(*) AS FISH_COUNT
    FROM FISH_INFO
    GROUP BY FISH_TYPE
), FISH_AVG_OVER AS (
    SELECT
        FTYA.ID,
        FTYA.MAX_LENGTH,
        FTYA.FISH_TYPE
    FROM FISH_TYPE_AVG FTYA
    JOIN FISH_TOTAL_AVG FTOA
    ON FTYA.TYPE_AVG &amp;gt;= FTOA.TOTAL_AVG
)
SELECT
    ID,
    MAX_LENGTH,
    FISH_TYPE
FROM FISH_AVG_OVER
ORDER BY FISH_TYPE;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1703837388518&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WITH FISH_TYPE_STATS AS (
    SELECT
        FISH_TYPE,
        COUNT(*) AS FISH_COUNT,
        MAX(IF(LENGTH IS NULL, 10, LENGTH)) AS MAX_LENGTH,
        AVG(IF(LENGTH IS NULL, 10, LENGTH)) AS AVG_LENGTH
    FROM FISH_INFO
    GROUP BY FISH_TYPE
), FILTERED_FISH AS (
    SELECT
        FISH_TYPE,
        FISH_COUNT,
        MAX_LENGTH
    FROM FISH_TYPE_STATS
    WHERE AVG_LENGTH &amp;gt;= 33
)
SELECT
    FISH_COUNT,
    MAX_LENGTH,
    FISH_TYPE
FROM FILTERED_FISH
ORDER BY FISH_TYPE ASC;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;FISH_TYPE_STATS CTE&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&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; (FISH_COUNT)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최대 길이&lt;/b&gt; (MAX_LENGTH): NULL인 경우 길이를 10으로 간주.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;평균 길이&lt;/b&gt; (AVG_LENGTH): NULL인 경우 길이를 10으로 간주.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;FILTERED_FISH CTE&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;평균 길이(AVG_LENGTH)가 33cm 이상인 물고기 종류만 선택한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최종 SELECT&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필터링된 결과에서 FISH_COUNT, MAX_LENGTH, FISH_TYPE를 출력하고, FISH_TYPE 기준으로 오름차순 정렬한다.&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;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제에 평균 33이라고 나와 있는데 테스트 케이스 마다 평균이 다를줄 알고 다르게 계산했다.&lt;/li&gt;
&lt;li&gt;심지어 10cm이하는 NULL이고 10으로 잡고 계산해야 하는데 이것 또한 지키지 못했다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL/다시 풀어 보기</category>
      <category>AVG</category>
      <category>group by</category>
      <category>If</category>
      <category>level 3</category>
      <category>MAX</category>
      <category>programmers</category>
      <category>SQL</category>
      <category>SQL 고득점 KIT</category>
      <category>특정 조건을 만족하는 물고기별 수와 최대 길이 구하기</category>
      <category>프로그래머스</category>
      <author>스위태니</author>
      <guid isPermaLink="true">https://sound-programming.tistory.com/425</guid>
      <comments>https://sound-programming.tistory.com/425#entry425comment</comments>
      <pubDate>Mon, 23 Dec 2024 21:02:55 +0900</pubDate>
    </item>
  </channel>
</rss>