<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>기매의 개발하는 김에</title>
    <link>https://maemae22.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 4 Jul 2026 00:49:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>기매_</managingEditor>
    <image>
      <title>기매의 개발하는 김에</title>
      <url>https://tistory1.daumcdn.net/tistory/5636780/attach/85836e09344a45bba327e003ec51f832</url>
      <link>https://maemae22.tistory.com</link>
    </image>
    <item>
      <title>인프런 컴퓨터구조 강의 요약</title>
      <link>https://maemae22.tistory.com/191</link>
      <description>&lt;h1 style=&quot;background-color: #101113; color: #ffffff; text-align: start;&quot;&gt;개발자를 위한 컴퓨터공학 1: 혼자 공부하는 컴퓨터구조 + 운영체제&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1745277107988&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;[지금 무료]개발자를 위한 컴퓨터공학 1: 혼자 공부하는 컴퓨터구조 + 운영체제 강의 | 강민철 - &quot; data-og-description=&quot;강민철 | , 개발자 필수지식 컴퓨터 구조와 운영체제강의 하나로 총정리!   개발자가 꼭 알아야 할컴퓨터 구조, 운영체제 총정리   IT 분야 베스트셀러 『혼자 공부하는 컴퓨터 구조 + 운영체&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FUahl/hyYH9pI6Gy/kUw1wKvIreAL2oxx2CyI40/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/kLIjK/hyYJwebVV9/mtqKE3j58tKl7iARnL7VBK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bXj672/hyYFyXZ186/KkYCYy5jcsntpH1iNcXS5k/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FUahl/hyYH9pI6Gy/kUw1wKvIreAL2oxx2CyI40/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/kLIjK/hyYJwebVV9/mtqKE3j58tKl7iARnL7VBK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bXj672/hyYFyXZ186/KkYCYy5jcsntpH1iNcXS5k/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781');&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;[지금 무료]개발자를 위한 컴퓨터공학 1: 혼자 공부하는 컴퓨터구조 + 운영체제 강의 | 강민철 -&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;강민철 | , 개발자 필수지식 컴퓨터 구조와 운영체제강의 하나로 총정리!   개발자가 꼭 알아야 할컴퓨터 구조, 운영체제 총정리   IT 분야 베스트셀러 『혼자 공부하는 컴퓨터 구조 + 운영체&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.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;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #e5f9f1; color: #212529; text-align: left;&quot;&gt;csnote: 컴퓨터과학 키워드 총정리 노트&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://csnote.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://csnote.net/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1745277137335&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;CSnote&quot; data-og-description=&quot;&quot; data-og-host=&quot;csnote.net&quot; data-og-source-url=&quot;https://csnote.net/&quot; data-og-url=&quot;https://csnote.net/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://csnote.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://csnote.net/&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;CSnote&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;csnote.net&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;2162&quot; data-origin-height=&quot;1074&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pnaWR/btsNtM1J51G/ljXkRpe7ooA48ZvAyUKcC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pnaWR/btsNtM1J51G/ljXkRpe7ooA48ZvAyUKcC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pnaWR/btsNtM1J51G/ljXkRpe7ooA48ZvAyUKcC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpnaWR%2FbtsNtM1J51G%2FljXkRpe7ooA48ZvAyUKcC1%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;2162&quot; height=&quot;1074&quot; data-origin-width=&quot;2162&quot; data-origin-height=&quot;1074&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;div&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;섹션 2. 컴퓨터 구조 시작하기&lt;/b&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;div id=&quot;mantine-jm92786hw-panel-item-1&quot; style=&quot;background-color: #ffffff;&quot; aria-hidden=&quot;false&quot;&gt;
&lt;h3 style=&quot;color: #212529;&quot; data-ke-size=&quot;size23&quot;&gt;[1] 컴퓨터 구조를 알아야 하는 이유&lt;/h3&gt;
&lt;p style=&quot;color: #212529;&quot; data-ke-size=&quot;size16&quot;&gt;1. 프로그래밍 언어의 문법과 함께 컴퓨터의 근간을 알아야 -&amp;gt; &lt;b&gt;문제 해결&lt;/b&gt; &amp;amp; 컴퓨터 분석 능력 향상 (프로그래밍 언어의 문법만으로는 해결하기 어려운 문제들 ex. 로컬 개발 환경에서 문제없이 돌아갔던 서비스가 배포 후 실사용 시 문제 생기는 경우)&lt;/p&gt;
&lt;p style=&quot;color: #212529;&quot; data-ke-size=&quot;size16&quot;&gt;2. 개발자는 &lt;b&gt;성능, 용량, 비용을 고려&lt;/b&gt;한 개발을 해야하며, 컴퓨터구조를 알아야 성능, 용량, 비용을 고려한 개발을 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #212529;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #212529;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;문법에 맞는 소스 코드를 컴퓨터에 입력만 하는 개발자&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #212529;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;-&amp;gt; 컴퓨터를 내려다보며 문제를 해결할 수 있는 개발자&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;color: #212529;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #212529;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;[2] 컴퓨터 구조의 큰 그림&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;- 컴퓨터 구조&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;1. 컴퓨터가 이해하는 정보&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;1-1. 데이터&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;1-2. 명령어 (컴퓨터 = 명령어를 처리하는 기계)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2. 컴퓨터의 네 가지 핵심 부품&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2-1. CPU&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2-2. 메모리(= 주기억장치 / RAM, &lt;s&gt;ROM&lt;/s&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2-3. 보조기억장치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2-4. 입출력장치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;948&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIYGpU/btsNw8o79Ie/NTBHCkdtc3QqyTXbJjxjDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIYGpU/btsNw8o79Ie/NTBHCkdtc3QqyTXbJjxjDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIYGpU/btsNw8o79Ie/NTBHCkdtc3QqyTXbJjxjDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIYGpU%2FbtsNw8o79Ie%2FNTBHCkdtc3QqyTXbJjxjDK%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;1504&quot; height=&quot;948&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;948&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h3 style=&quot;color: #212529;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #212529;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;[3] [추가] 컴퓨터의 네 가지 핵심 부품 직접 확인하기&lt;/span&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/div&gt;</description>
      <category>Computer science (CS)/컴퓨터구조</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/191</guid>
      <comments>https://maemae22.tistory.com/191#entry191comment</comments>
      <pubDate>Tue, 22 Apr 2025 08:25:10 +0900</pubDate>
    </item>
    <item>
      <title>Oracle 기초 공부하기</title>
      <link>https://maemae22.tistory.com/136</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;본격 시작 전 준비해야 할 것&lt;/h4&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. Oracle DB 설치 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://backendcode.tistory.com/266&quot;&gt;https://backendcode.tistory.com/266&lt;/a&gt;&amp;nbsp;또는&amp;nbsp;&lt;a href=&quot;https://old-developer.tistory.com/119&quot;&gt;https://old-developer.tistory.com/119&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. Oracle SQL Developer / DBeaver 설치&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약 2번의 Oracle SQL Developer를 설치하고 유저를 생성하는 과정에서&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;background-color: #ffffff; color: #0d0d0d; text-align: start;&quot;&gt;상태: 실패 -테스트 실패: ORA-01017: 사용자명/비밀번호가 부적합, 로그온할 수 없습니다.&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #0d0d0d;&quot;&gt;라는 문구가 뜬다면 유저 아이디를 아래와 같이 해보는 것을 추천함 !&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWNM5m/btsEViz1hhk/JespGquruK6AFLNBZR2KH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWNM5m/btsEViz1hhk/JespGquruK6AFLNBZR2KH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWNM5m/btsEViz1hhk/JespGquruK6AFLNBZR2KH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWNM5m%2FbtsEViz1hhk%2FJespGquruK6AFLNBZR2KH1%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;410&quot; height=&quot;550&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL&amp;nbsp;Developer&amp;nbsp;줄번호&amp;nbsp;표시 &lt;br /&gt;&amp;gt;&amp;nbsp;도구&amp;nbsp;&amp;gt;&amp;nbsp;환경설정&amp;nbsp;&amp;gt;&amp;nbsp;코드편집기&amp;nbsp;&amp;gt;&amp;nbsp;행여백&amp;nbsp;&amp;gt;&amp;nbsp;행번호표시&amp;nbsp;체크 &lt;br /&gt;&lt;br /&gt;DBeaver&amp;nbsp;줄번호&amp;nbsp;표시 &lt;br /&gt;윈도우&amp;nbsp;-&amp;nbsp;설정&amp;nbsp;-&amp;nbsp;편집기&amp;nbsp;-&amp;nbsp;문서편집기&amp;nbsp;-&amp;nbsp;show&amp;nbsp;line&amp;nbsp;numbers&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;USER 생성&lt;/h4&gt;
&lt;pre id=&quot;code_1707978909395&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 12C 버전부터 c## 이 생겨서, 이전 버전과 같이 사용하고자 아래 구문 실행 
-- 자세한 내용은 - 구글링으로 아래 에러 검색 
-- ORA-65096: 공통 사용자 또는 롤 이름이 부적합합니다.
ALTER SESSION SET &quot;_ORACLE_SCRIPT&quot;=true;

-- 이유는 모르겠지만, 첫번째 계정으로 scott / tiger 를 만들어야 할것 같은..
create user scott identified by tiger;

-- 접속 권한 부여
grant connect, resource to scott;

-- 테이블스페이스 사용 권한 부여
alter user scott quota unlimited on users;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cf. Ctrl+Enter 또는 F9 으로 실행 가능 ! / F5는 스크립트 전체 실행&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Connection&amp;nbsp;&amp;amp;&amp;nbsp;Table&amp;nbsp;생성&lt;/h4&gt;
&lt;pre id=&quot;code_1707979621515&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE coffee_menu (
 no number GENERATED AS IDENTITY ,
 coffee VARCHAR2(100) NOT NULL ,
 kind VARCHAR2(100) NOT NULL ,
 price number(11) DEFAULT 0 NOT NULL,
 reg_day date DEFAULT sysdate NOT NULL ,
 mod_day date DEFAULT sysdate NOT NULL ,
 CONSTRAINT pk_coffee_menu PRIMARY KEY(no)
)
;

COMMENT ON TABLE coffee_menu IS '커피/음료 메뉴';

-----------------------------------------------------

CREATE TABLE cust_info (
 no number GENERATED AS IDENTITY ,
 cust_id VARCHAR2(100) NOT NULL,
 name VARCHAR2(100) NOT NULL,
 email VARCHAR2(100) NOT NULL,
 role VARCHAR2(100) DEFAULT 'MEMBER' NOT NULL  ,
 reg_day date default sysdate NOT NULL,
 CONSTRAINT pk_cust_info PRIMARY KEY(no)
);


COMMENT ON TABLE cust_info IS '고객정보';

-- unique index 생성

ALTER TABLE cust_info ADD CONSTRAINT idx_cust_info UNIQUE(cust_id);

-----------------------------------------------------

CREATE TABLE order_list (
 no number GENERATED AS IDENTITY ,
 coffee_no number(11) NOT NULL,
 coffee VARCHAR2(100) NOT NULL,
 price number(11) NOT NULL,
 cust_id VARCHAR2(100) NOT NULL,
 name VARCHAR2(100) NOT NULL,
 reg_day date default sysdate ,
 CONSTRAINT pk_order_list PRIMARY KEY(no)
);


COMMENT ON TABLE order_list IS '주문내역';

-- foreign key 생성

ALTER TABLE order_list
ADD CONSTRAINT fk_coffee_no
FOREIGN KEY (coffee_no)
REFERENCES coffee_menu(no);

ALTER TABLE order_list
ADD CONSTRAINT fk_cust_id
FOREIGN KEY (cust_id)
REFERENCES cust_info(cust_id);&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;INSERT&lt;/h4&gt;
&lt;pre id=&quot;code_1707980157162&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO 테이블명 (컬럼명, 컬럼명, 컬럼명)
VALUES (값1, 값2, 값3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시&lt;/p&gt;
&lt;pre id=&quot;code_1707980094250&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('아메리카노','커피',2000);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('카페라떼','커피',3000);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('카푸치노','커피',3000);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('그린티','논커피',3500);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('초코라떼','논커피',4000);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('파인애플','에이드',3000);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('제주한라봉','에이드',3000);

INSERT INTO coffee_menu (coffee, kind, price)
VALUES ('오렌지','에이드',3000);

-------------------------------------

INSERT INTO cust_info(cust_id,NAME,email,role)
VALUES('ID1','홍길동','email1@hong.com','MEMBER');

INSERT INTO cust_info(cust_id,NAME,email,role)
VALUES('ID2','홍길성','email2@hong.com','MEMBER');

INSERT INTO cust_info(cust_id,NAME,email,role)
VALUES('ID3','홍길자','email3@hong.com','MEMBER');

INSERT INTO cust_info(cust_id,NAME,email,role)
VALUES('ID4','홍길순','email4@hong.com','MEMBER');

INSERT INTO cust_info(cust_id,NAME,email,role)
VALUES('ID5','홍길선','email5@hong.com','MEMBER');

INSERT INTO cust_info(cust_id,NAME,email,role)
VALUES('ID6','관리자','admin@hong.com','ADMIN');

--------------------------------------

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(1,'아메리카노',2000,'ID1','홍길동');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(1,'아메리카노',2000,'ID2','홍길성');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(3,'카푸치노',3000,'ID3','홍길자');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(3,'카푸치노',3000,'ID3','홍길자');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(5,'초코라떼',4000,'ID4','홍길순');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(8,'오렌지',3000,'ID2','홍길성');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(4,'그린티',3500,'ID3','홍길자');

INSERT INTO order_list (coffee_no,coffee,price,cust_id,NAME)
VALUES(2,'카페라떼',3000,'ID5','홍길선');&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SELECT - 단일 테이블&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SQL의 문법 순서와 실행 순서는 서로 다르다&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;[&amp;nbsp;문법&amp;nbsp;작성&amp;nbsp;순서&amp;nbsp;]&lt;/span&gt; &lt;br /&gt;① SELECT 컬럼명&lt;br /&gt;② FROM 테이블명&lt;br /&gt;③ WHERE 조건식 (IN, LIKE, EXIST 등)&lt;br /&gt;④ GROUP BY 컬럼명&lt;br /&gt;⑤ HAVING 조건식&lt;br /&gt;⑥ ORDER BY 칼럼명 (ASC, DESC)&lt;/p&gt;
&lt;pre id=&quot;code_1707980753751&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
  CategoryID,
  MAX(Price) AS MaxPrice, 
  MIN(Price) AS MinPrice,
  TRUNCATE((MAX(Price) + MIN(Price)) / 2, 2) AS MedianPrice,
  TRUNCATE(AVG(Price), 2) AS AveragePrice
FROM Products
WHERE CategoryID &amp;gt; 2
GROUP BY CategoryID
HAVING
  AveragePrice BETWEEN 20 AND 30
  AND MedianPrice &amp;lt; 40;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;[&amp;nbsp;실행&amp;nbsp;작동&amp;nbsp;순서&amp;nbsp;]&lt;/span&gt; &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;① FROM&lt;/span&gt;&lt;br /&gt;② ON&lt;br /&gt;③ JOIN&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;④ WHERE&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;⑤ GROUP BY&lt;/span&gt;&lt;br /&gt;⑥ CUBE | ROLLUP&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;⑦ HAVING&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;⑧ SELECT&lt;/span&gt;&lt;br /&gt;⑨ DISTINCT&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;⑩ ORDER BY&lt;/span&gt;&lt;br /&gt;⑪&amp;nbsp;TOP &lt;br /&gt;&lt;br /&gt;실행&amp;nbsp;작동순서를&amp;nbsp;자주&amp;nbsp;사용하는&amp;nbsp;파란색&amp;nbsp;글씨로&amp;nbsp;된&amp;nbsp;쿼리문만&amp;nbsp;설명하면, &lt;br /&gt;1. 조회 테이블 확인(&lt;b&gt;FROM&lt;/b&gt;)&lt;br /&gt;2. 데이터 추출 조건 확인(&lt;b&gt;WHERE&lt;/b&gt;)&lt;br /&gt;3. 컬럼 그룹화(&lt;b&gt;GROUP BY&lt;/b&gt;)&lt;br /&gt;4. 그룹화 조건(&lt;b&gt;HAVING&lt;/b&gt;)&lt;br /&gt;5. 데이터 추출(&lt;b&gt;SELECT&lt;/b&gt;)&lt;br /&gt;6.&amp;nbsp;데이터&amp;nbsp;순서&amp;nbsp;정렬(&lt;b&gt;ORDER&amp;nbsp;BY&lt;/b&gt;) &lt;br /&gt;&lt;br /&gt;순으로&amp;nbsp;이루어진다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SELECT&amp;nbsp;-&amp;nbsp;Table&amp;nbsp;Join&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ JOIN ]&lt;/p&gt;
&lt;pre id=&quot;code_1707998496698&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ~~ 
FROM TABLE_A A (LEFT|생략(INNER)|RIGHT|FULL) JOIN TABLE_B B ON A.KEY=B.KEY&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;SELECT&amp;nbsp;Subquery&lt;/h4&gt;
&lt;pre id=&quot;code_1707998539275&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * 
FROM 테이블명 
WHERE (컬럼1, 컬럼2) IN (SELECT 서브쿼리_컬럼1, 서브쿼리_컬럼2 FROM 서브쿼리_테이블);&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;UPDATE&lt;/h4&gt;
&lt;pre id=&quot;code_1707999215233&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;UPDATE 테이블명
SET 컬럼=값, 컬럼=값
WHERE 검색조건 (=, IN, LIKE, EXIST)

-- UPDATE문에 Subquery 사용하기
UPDATE 테이블명
SET (컬럼, 컬럼) = (select 컬럼명 from 테이블명 where 조건문)
WHERE 검색조건 (=, IN, LIKE, EXIST)
	  검색조건 = (select 컬럼명 from 테이블명 where 조건문)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;DELETE&lt;/h4&gt;
&lt;pre id=&quot;code_1707999697496&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DELETE 테이블명
WHERE 검색조건 (=, IN, LIKE, EXIST)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;VIEW&amp;nbsp;생성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뷰를 생성할 수 있는 권한을 주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VIEW를 생성. (SELECT Query 작성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 뷰=테이블 비슷하게 사용 가능함. FROM절에 뷰 이름 입력. WHERE절도 사용 가능함.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;+ 더 공부하면 좋을 것들&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 오라클 내장 함수 &lt;br /&gt;ex. to_char, to_number, to_date, nvl, decode, case, length, trim&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;오라클&amp;nbsp;분석/집계&amp;nbsp;함수 &lt;br /&gt;ex. count(), min(), max(), avg(), over(), partition by&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;Index &lt;br /&gt;-&amp;nbsp;인덱스&amp;nbsp;이해,&amp;nbsp;인덱스의&amp;nbsp;올바른&amp;nbsp;생성,&amp;nbsp;사용 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4.&amp;nbsp;PL/SQL&amp;nbsp;(Trigger) &lt;br /&gt;-&amp;nbsp;DBMS&amp;nbsp;자체로&amp;nbsp;프로그램을 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&amp;nbsp;사이트 &lt;br /&gt;-&amp;nbsp;Live&amp;nbsp;SQL&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://livesql.oracle.com/apex/f?p=590:49::::RP::&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://livesql.oracle.com/apex/f?p=590:49::::RP::&lt;/a&gt;&lt;br /&gt;-&amp;nbsp;IT늦공&amp;nbsp;유툽&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=OSglfI54C78&amp;amp;list=PL3036mp45iYxIWncxyM8QCwv-4st7wucz&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=OSglfI54C78&amp;amp;list=PL3036mp45iYxIWncxyM8QCwv-4st7wucz&lt;/a&gt;&lt;/p&gt;</description>
      <category>DB : MySQL | Oracle | MyBatis</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/136</guid>
      <comments>https://maemae22.tistory.com/136#entry136comment</comments>
      <pubDate>Thu, 15 Feb 2024 20:12:17 +0900</pubDate>
    </item>
    <item>
      <title>TreeSet 사용 시 주의할 점 : 정렬 기준에서 동일한 순위를 차지하는 객체는 중복으로 처리된다 !</title>
      <link>https://maemae22.tistory.com/122</link>
      <description>&lt;pre id=&quot;code_1690438753703&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.TreeSet;

public class P05_CPU스케쥴링복사 {
    public int[] solution(int[][] tasks) {
        int[] answer = new int[tasks.length];
        TreeSet&amp;lt;AllCp&amp;gt; all = new TreeSet&amp;lt;&amp;gt;();

        for (int i=0; i&amp;lt;tasks.length; i++) {
            all.add(new AllCp(i, tasks[i][0], tasks[i][1]));
        }
        System.out.println(&quot;tasks.length = &quot; + tasks.length + &quot; / &quot; + &quot;all.size() = &quot;+all.size());
        return answer;
    }

    public static void main(String[] args) {
        P05_CPU스케쥴링복사 T = new P05_CPU스케쥴링복사();
        System.out.println(Arrays.toString(T.solution(new int[][]{{2, 3}, {1, 2}, {8, 2}, {3, 1}, {10, 2}})));
        System.out.println(Arrays.toString(T.solution(new int[][]{{5, 2}, {7, 3}, {1, 3}, {1, 5}, {2, 2}, {1, 1}})));
        System.out.println(Arrays.toString(T.solution(new int[][]{{1, 2}, {2, 3}, {1, 3}, {3, 3}, {8, 2}, {1, 5}, {2, 2}, {1, 1}})));
        System.out.println(Arrays.toString(T.solution(new int[][]{{999, 1000}, {996, 1000}, {998, 1000}, {999, 7}})));
    }
}

class AllCp implements Comparable&amp;lt;AllCp&amp;gt; {
    int num;
    int start;
    int time;
    AllCp(int num, int start, int time) {
        this.num = num;
        this.start = start;
        this.time = time;
    }

    @Override
    public int compareTo(AllCp o) {
        return this.start - o.start;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드를 실행시키면 아래와 같은 결과가 나온다.&lt;/p&gt;
&lt;pre id=&quot;code_1690438797765&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tasks.length = 5 / all.size() = 5
[0, 0, 0, 0, 0]
tasks.length = 6 / all.size() = 4
[0, 0, 0, 0, 0, 0]
tasks.length = 8 / all.size() = 4
[0, 0, 0, 0, 0, 0, 0, 0]
tasks.length = 4 / all.size() = 3
[0, 0, 0, 0]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new AllCp(i, tasks[i][0], tasks[i][1]) 으로 새로운 AllCp 클래스를 만들 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 클래스는 없으므로 당연히 TreeSet의 사이즈가 배열의 사이즈와 동일할거라고 생각했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 tasks.length = 6 / all.size() = 4 으로 다른 것을 확인하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유를 찾아보니 다음과 같았다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TreeSet은 중복된 값을 허용하지 않는 자료구조이며, 정렬 기준에서 동일한 순위를 차지하는 객체는 중복으로 처리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확히는 compareTo 메서드의 결과가 0인 경우 동일한 순위로 간주되고 중복으로 처리된다. &lt;br /&gt;&lt;br /&gt;따라서 만약 두 객체가 compareTo 메서드에서 동일한 값을 반환한다면, TreeSet은 두 객체를 중복으로 간주하고 둘 중 하나만 유지한다. 또한 중복을 허용하지 않기 때문에 새로운 객체를 추가할 때 기존 TreeSet에 이미 동일한 순위의 객체가 있다면 새로운 객체가 추가되지 않는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TreeSet이 중복을 허용하지 않는다는 것은 알았지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복을 판단하는 기준이 compareTo 메서드의 반환값(동일한 우선순위)인줄은 몰랐어서 문제의 답이 나오지 않던 것이였다 .. !&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째 케이스를 예시로 보면, 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1690439366624&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{5, 2}, {7, 3}, {1, 3}, {1, 5}, {2, 2}, {1, 1}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 길이는 6이지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AllCp 정렬의 기준인 1열의 값이 배열의 3,4,6번째가 1로 동일하므로 중복으로 처리되어 &lt;b&gt;3개가 아닌 &lt;span style=&quot;background-color: #ffc9af;&quot;&gt;1개로 카운팅&lt;/span&gt;&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 알았으니 앞으로 알고리즘 문제 풀 때 주의하기 !&lt;/p&gt;</description>
      <category>알고리즘 문제풀이 (자료구조)</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/122</guid>
      <comments>https://maemae22.tistory.com/122#entry122comment</comments>
      <pubDate>Thu, 27 Jul 2023 15:32:36 +0900</pubDate>
    </item>
    <item>
      <title>MySQL 문법 정리 (w. 프로그래머스 SQL Lv. 4 문제 풀이 -2)</title>
      <link>https://maemae22.tistory.com/120</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[1] JOIN 여러번&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1688358796708&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/132204

# PATIENT, DOCTOR 그리고 APPOINTMENT 테이블에서 2022년 4월 13일 취소되지 않은 흉부외과(CS) 진료 예약 내역을 조회하는 SQL문을 작성해주세요.
# 진료예약번호, 환자이름, 환자번호, 진료과코드, 의사이름, 진료예약일시 항목이 출력되도록 작성해주세요.
# 결과는 진료예약일시를 기준으로 오름차순 정렬해주세요.
SELECT A.APNT_NO, P.PT_NAME, P.PT_NO, D.MCDP_CD, D.DR_NAME, A.APNT_YMD FROM APPOINTMENT A
    JOIN PATIENT P ON A.PT_NO=P.PT_NO
    JOIN DOCTOR D ON A.MDDR_ID=D.DR_ID
    WHERE A.APNT_CNCL_YN='N' AND DATE_FORMAT(A.APNT_YMD, &quot;%Y%m%d&quot;)='20220413' AND A.MCDP_CD='CS'
    ORDER BY A.APNT_YMD ASC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번 JOIN할 때와 동일한 방법으로 &lt;u&gt;JOIN 테이블 ON 컬럼=컬럼&lt;/u&gt; 을 통해 &lt;u&gt;여러 테이블을 JOIN&lt;/u&gt; 할 수 있다 !&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+&lt;/p&gt;
&lt;pre id=&quot;code_1688451278123&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/144856

# 2022년 1월의 도서 판매 데이터를 기준으로 저자 별, 카테고리 별 매출액(TOTAL_SALES = 판매량 * 판매가) 을 구하여,
# 저자 ID(AUTHOR_ID), 저자명(AUTHOR_NAME), 카테고리(CATEGORY), 매출액(SALES) 리스트를 출력하는 SQL문을 작성해주세요.
# 결과는 저자 ID를 오름차순으로, 저자 ID가 같다면 카테고리를 내림차순 정렬해주세요.
SELECT B.AUTHOR_ID, A.AUTHOR_NAME, B.CATEGORY, SUM(B.PRICE*S.SUM) SALES FROM BOOK B
    JOIN AUTHOR A ON B.AUTHOR_ID=A.AUTHOR_ID
    JOIN (SELECT BOOK_ID, SUM(SALES) SUM FROM BOOK_SALES B WHERE DATE_FORMAT(SALES_DATE, &quot;%Y%m&quot;)='202201' GROUP BY BOOK_ID) S ON B.BOOK_ID=S.BOOK_ID
    GROUP BY B.AUTHOR_ID, B.CATEGORY
    ORDER BY B.AUTHOR_ID ASC, B.CATEGORY DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[2] &lt;u&gt;사용자 정의 변수&lt;/u&gt; 선언 및 사용, UNION, UNION ALL&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제&lt;/blockquote&gt;
&lt;pre id=&quot;code_1688531793124&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/59413

# 보호소에서는 몇 시에 입양이 가장 활발하게 일어나는지 알아보려 합니다. 
# 0시부터 23시까지, 각 시간대별로 입양이 몇 건이나 발생했는지 조회하는 SQL문을 작성해주세요. 
# 이때 결과는 시간대 순으로 정렬해야 합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;풀이 1 : 사용자 정의 변수 사용 (1)&lt;/blockquote&gt;
&lt;pre id=&quot;code_1688531930129&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET @i = -1;
SELECT H.HOUR, IFNULL(C.COUNT, 0)
FROM (SELECT @i:=@i+1 HOUR FROM ANIMAL_OUTS WHERE @i&amp;lt;23) H
    LEFT JOIN (SELECT HOUR(DATETIME) HOUR, COUNT(ANIMAL_ID) COUNT FROM ANIMAL_OUTS GROUP BY HOUR(DATETIME)) C ON H.HOUR=C.HOUR
ORDER BY H.HOUR&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;풀이 2 : 사용자 정의 변수 사용 (2)&lt;/blockquote&gt;
&lt;pre id=&quot;code_1688531939626&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET @i = -1;
SELECT @i:=@i+1 HOUR, (SELECT COUNT(ANIMAL_ID) FROM ANIMAL_OUTS WHERE HOUR(DATETIME)=@i) COUNT
FROM ANIMAL_OUTS
WHERE @i&amp;lt;23
ORDER BY HOUR&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;풀이 3 : UNION ALL 사용 (깔끔한 풀이 방법은 아니다 ...)&lt;/blockquote&gt;
&lt;pre id=&quot;code_1688531953481&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT H.HOUR, IFNULL(C.COUNT, 0) COUNT FROM
(SELECT 0 HOUR UNION ALL
 SELECT 1 UNION ALL
 SELECT 2 UNION ALL
 SELECT 3 UNION ALL
 SELECT 4 UNION ALL
 SELECT 5 UNION ALL
 SELECT 6 UNION ALL
 SELECT 7 UNION ALL
 SELECT 8 UNION ALL
 SELECT 9 UNION ALL
 SELECT 10 UNION ALL
 SELECT 11 UNION ALL
 SELECT 12 UNION ALL
 SELECT 13 UNION ALL
 SELECT 14 UNION ALL
 SELECT 15 UNION ALL
 SELECT 16 UNION ALL
 SELECT 17 UNION ALL
 SELECT 18 UNION ALL
 SELECT 19 UNION ALL
 SELECT 20 UNION ALL
 SELECT 21 UNION ALL
 SELECT 22 UNION ALL
 SELECT 23) H
    LEFT JOIN (SELECT HOUR(DATETIME) HOUR, COUNT(ANIMAL_ID) COUNT FROM ANIMAL_OUTS GROUP BY HOUR(DATETIME)) C ON H.HOUR=C.HOUR
ORDER BY H.HOUR&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 해당 문제를 읽은 직후, &lt;s&gt;(정답이 아닐걸 알면서도)&lt;/s&gt; 아래와 같은 쿼리를 생각할 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1688532271532&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT HOUR(DATETIME) HOUR, COUNT(ANIMAL_ID) COUNT FROM ANIMAL_OUTS GROUP BY HOUR(DATETIME) ORDER BY HOUR ASC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 위 쿼리의 실행 결과로는 HOUR 컬럼이 7~19시까지밖에 나오지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제에서 요구한 0~23시와는 다르므로 오답이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0~23시로 표현되게 하려면 어떻게 해야할까 ?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 정의 변수를 활용해보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용자 정의 변수 :&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 직접 정의하는 변수로, 한 명령문에서 값을 저장하고 다른 명령문에서 참조할 수 있다. 이를 통해 한 명령문에서 다른 명령문으로 값을 전달할 수 있다.&lt;br /&gt;사용자 정의 변수는 @var_name으로 작성하며, 변수 이름은 영문, 숫자, ., _, 등으로 구성될 수 있다. 그리고 대소문자를 구분하지 않는다.&lt;br /&gt;또한&amp;nbsp;&amp;nbsp;세션(session)&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;없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;선언 (SET) : SET문을 활용한 사용자 정의 변수 선언 : 연산자 = 와 := 모두 사용 가능&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688532562891&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET @var_name = VALUE
SET @var_name := VALUE

# 예시
SET @var = 1;
SET @var := 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;선언 (SELECT) : SELECT 문&lt;/b&gt;을 실행해서 사용자 정의 변수를 선언할 수도 있다. SET문을 실행할 때와는 다르게 대입 시 &lt;b&gt;:= 연산자&lt;/b&gt;를 사용한다. &lt;u&gt;(= 연산자는 사용 불가능함)&lt;/u&gt; 초기화하지 않은 변수는 null로 설정된다.&lt;/p&gt;
&lt;pre id=&quot;code_1688532697346&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT @var_name;
SELECT @var_name := VALUE;

# 예시
SELECT @var;
SELECT @var := 2;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조 : SQL문에&amp;nbsp;변수&amp;nbsp;이름을&amp;nbsp;기재하여&amp;nbsp;참조&lt;/b&gt;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;pre id=&quot;code_1688532749576&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET @start = 1, @finish = 10;

SELECT * FROM tb_code WHERE code_cd BETWEEN @start AND @finish;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1688533192316&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET @i = -1;
SELECT @i:=@i+1 HOUR FROM ANIMAL_OUTS WHERE @i&amp;lt;23&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 쿼리를 실행하면 의도한대로 &lt;u&gt;HOUR 컬럼이 0부터 23까지&lt;/u&gt; 나오는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 LEFT JOIN 하여 IFNULL 함수를 통해 COUNT가 NULL일 경우 0이 출력되도록 설정하여 문제를 해결한 것이 풀이 1번이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 비슷하지만 다른 방법으로, SUBQUERY를 통해 변수와 같은 시간대의 COUNT 값을 출력하고 값이 없는 경우 자동으로 0이 출력되게 하여 문제를 해결한 것이 풀이 2번이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;UNION, UNION ALL : 합집합&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UNION&lt;/b&gt; : 쿼리의 결과를 합친다. &lt;b&gt;중복&lt;/b&gt;된 ROW는 &lt;b&gt;제거&lt;/b&gt; (DISTINCT)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;UNION ALL&lt;/b&gt; : 쿼리의 결과를 합친다. &lt;b&gt;중복&lt;/b&gt;된 ROW &lt;b&gt;제거 X&lt;/b&gt; (모든 컬럼값이 같은 ROW도 중복으로 보여줌)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 합치려는 테이블들의 &lt;u&gt;컬럼 수, 컬럼 데이터 형식이 모두 일치&lt;/u&gt;해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UNION은 중복 제거를 하기 때문에 내부 &lt;b&gt;정렬&lt;/b&gt;이 일어나고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UNION ALL은 중복 제거하지 않으므로 정렬을 유발하지 않아서 UNION 보다 속도가 빠르다 !&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 둘 중 아무거나 상관없는 상황이라면 UNION 보다는 UNION ALL을 사용하는 게 좋으며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UNION을 사용해야 한다면, 최소 필요 컬럼만 SELECT 해서 사용하는 것이 좋다.&lt;/p&gt;
&lt;pre id=&quot;code_1688601883851&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CustomerName AS Name, City, Country, 'CUSTOMER'
FROM Customers
UNION
SELECT SupplierName AS Name, City, Country, 'SUPPLIER'
FROM Suppliers
ORDER BY Name;&lt;/code&gt;&lt;/pre&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; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MINUS(EXCEPT) : 차집합 - &lt;u&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;MySQL 지원X&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;선행&lt;/b&gt; SELECT 문에는 &lt;b&gt;있고&lt;/b&gt;, &lt;b&gt;후행&lt;/b&gt; SELECT 문에는 &lt;b&gt;없는&lt;/b&gt; 집합을 조회한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSSQL에서는 EXCEPT로 쓴다.&lt;/p&gt;
&lt;pre id=&quot;code_1688602447877&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT DEPTNO FROM DEPT
MINUS
SELECT DEPTNO FROM EMP;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;풀이 3번&lt;/b&gt;에서 UNION ALL로 이어진 테이블은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;컬럼명이 HOUR이며 데이터가 0~23인 테이블&lt;/u&gt;이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;HOUR(시간)&amp;nbsp;테이블을&amp;nbsp;각&amp;nbsp;시간대별로&amp;nbsp;입양&amp;nbsp;건수를&amp;nbsp;나타내는&amp;nbsp;COUNT&amp;nbsp;테이블과&amp;nbsp;LEFT&amp;nbsp;JOIN하여&amp;nbsp;문제를&amp;nbsp;해결할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이때&amp;nbsp;IFNULL을&amp;nbsp;활용하여&amp;nbsp;COUNT&amp;nbsp;값이&amp;nbsp;없을&amp;nbsp;때(NULL일&amp;nbsp;때)&amp;nbsp;0으로&amp;nbsp;표시하도록&amp;nbsp;설정했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[3]&lt;span&gt; &lt;/span&gt;UNION, UNION ALL 사용 시 주의점 (UNION + WHERE)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1688606300215&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/131537

# ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의
# 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요.
# OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요.
# 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.
SELECT DATE_FORMAT(SALES_DATE, &quot;%Y-%m-%d&quot;) SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT FROM ONLINE_SALE
    WHERE DATE_FORMAT(SALES_DATE, &quot;%Y%m&quot;)='202203'
UNION ALL
SELECT DATE_FORMAT(SALES_DATE, &quot;%Y-%m-%d&quot;) SALES_DATE, PRODUCT_ID, NULL USER_ID, SALES_AMOUNT FROM OFFLINE_SALE
    WHERE DATE_FORMAT(SALES_DATE, &quot;%Y%m&quot;)='202203'
ORDER BY SALES_DATE ASC, PRODUCT_ID ASC, USER_ID ASC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UNION, UNION ALL 사용 시 &lt;b&gt;&lt;u&gt;합집합을 적용한 후 WHERE을 사용해서는 안된다&lt;/u&gt;&lt;/b&gt;. (&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;ORDER BY는 가능&lt;/b&gt;&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어,&lt;/p&gt;
&lt;pre id=&quot;code_1688606485973&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT FROM ONLINE_SALE
UNION ALL
SELECT SALES_DATE, PRODUCT_ID, NULL USER_ID, SALES_AMOUNT FROM OFFLINE_SALE
WHERE DATE_FORMAT(SALES_DATE, &quot;%Y%m&quot;)='202203'
ORDER BY SALES_DATE ASC, PRODUCT_ID ASC, USER_ID ASC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 사용하면 안된다. (에러는 나지 않지만, 우리가 의도한대로 데이터를 얻을 수 없다. WHERE 절이 없을 때와 결과가 똑같이 나온다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 위에 적어둔 쿼리처럼 각 개별 SELECT문에 WHERE 절을 각각 적용하거나&lt;/p&gt;
&lt;pre id=&quot;code_1688606672201&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT *
  FROM (SELECT * FROM TableA
        UNION
        SELECT * FROM TableB
       ) AS U
 WHERE U.Col1 = ...
 
 
 SELECT * FROM (
    SELECT * FROM Table1 WHERE Field1 = Value1
    UNION
    SELECT * FROM Table2 WHERE Field1 = Value2
) AS t WHERE Field2 = Value3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 방법처럼 한번 감싸서, 감싼 테이블에 WHERE 절을 적용해야 한다.&lt;/p&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;pre id=&quot;code_1688607114014&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM (
	SELECT DATE_FORMAT(SALES_DATE, &quot;%Y-%m-%d&quot;) SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT FROM ONLINE_SALE
	UNION ALL
	SELECT DATE_FORMAT(SALES_DATE, &quot;%Y-%m-%d&quot;) SALES_DATE, PRODUCT_ID, NULL USER_ID, SALES_AMOUNT FROM OFFLINE_SALE
) T
WHERE DATE_FORMAT(SALES_DATE, &quot;%Y%m&quot;)='202203'
ORDER BY SALES_DATE ASC, PRODUCT_ID ASC, USER_ID ASC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 작성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 T 같이 테이블 Alias를 주지 않으면&lt;/p&gt;
&lt;pre id=&quot;code_1688607287831&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Every derived table must have its own alias&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 에러가 뜬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;u&gt;테이블 Alias를 꼭 작성하도록 하자.&lt;/u&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB : MySQL | Oracle | MyBatis</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/120</guid>
      <comments>https://maemae22.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 3 Jul 2023 13:41:00 +0900</pubDate>
    </item>
    <item>
      <title>MySQL 문법 정리 (w. 프로그래머스 SQL Lv. 4 문제 풀이 -1)</title>
      <link>https://maemae22.tistory.com/119</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[ 이전글 (프로그래머스 SQL 3단계 문제 풀이 및 문법 정리) ]&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://maemae22.tistory.com/118&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://maemae22.tistory.com/118&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687755573514&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;MySQL 문법 정리 (w. 프로그래머스 SQL Lv. 3 문제 풀이)&quot; data-og-description=&quot;프로그래머스 SQL 문제를 풀면서 헷갈렸던 문법들을 정리해보자. 그 전에, SQL 구문(문법) 순서에 대해서 알아보자 [SQL 구문의 순서] SELECT 컬럼명 --------------------- (5) FROM 테이블명 ------------------- (1&quot; data-og-host=&quot;maemae22.tistory.com&quot; data-og-source-url=&quot;https://maemae22.tistory.com/118&quot; data-og-url=&quot;https://maemae22.tistory.com/118&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/tkwel/hyS8s8RpxF/nxmZFsQzLGAFAKF6gsSi41/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bheOaL/hyS8mU6VKt/HhKwIZW1VXi0JhKsSliM60/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://maemae22.tistory.com/118&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://maemae22.tistory.com/118&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/tkwel/hyS8s8RpxF/nxmZFsQzLGAFAKF6gsSi41/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bheOaL/hyS8mU6VKt/HhKwIZW1VXi0JhKsSliM60/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;MySQL 문법 정리 (w. 프로그래머스 SQL Lv. 3 문제 풀이)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스 SQL 문제를 풀면서 헷갈렸던 문법들을 정리해보자. 그 전에, SQL 구문(문법) 순서에 대해서 알아보자 [SQL 구문의 순서] SELECT 컬럼명 --------------------- (5) FROM 테이블명 ------------------- (1&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;maemae22.tistory.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;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[1] JOIN, LIKE, REGEXP(LIKE 여러개), 서브쿼리&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687755662035&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/59045

# 보호소에서 중성화 수술을 거친 동물 정보를 알아보려 합니다.
# 보호소에 들어올 당시에는 중성화되지 않았지만, 보호소를 나갈 당시에는 중성화된 동물의 아이디와 생물 종, 이름을 아이디 순으로 조회하는 SQL 문을 작성해주세요.
# 중성화를 거치지 않은 동물은 성별 및 중성화 여부에 Intact, 중성화를 거친 동물은 Spayed 또는 Neutered라고 표시되어있습니다.
SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME FROM ANIMAL_INS I JOIN ANIMAL_OUTS O ON I.ANIMAL_ID=O.ANIMAL_ID
    WHERE I.SEX_UPON_INTAKE LIKE '%Intact%' AND (O.SEX_UPON_OUTCOME LIKE '%Spayed%' OR O.SEX_UPON_OUTCOME LIKE '%Neutered%')
    ORDER BY I.ANIMAL_ID ASC

SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME FROM ANIMAL_INS I JOIN ANIMAL_OUTS O ON I.ANIMAL_ID=O.ANIMAL_ID
    WHERE I.SEX_UPON_INTAKE LIKE '%Intact%' AND O.SEX_UPON_OUTCOME REGEXP ('Spayed|Neutered')
    ORDER BY I.ANIMAL_ID ASC

SELECT ANIMAL_ID, ANIMAL_TYPE, NAME FROM ANIMAL_INS
    WHERE ANIMAL_ID IN (SELECT ANIMAL_ID FROM ANIMAL_OUTS WHERE SEX_UPON_OUTCOME REGEXP ('Spayed|Neutered'))
      AND SEX_UPON_INTAKE LIKE '%Intact%'
    ORDER BY ANIMAL_ID ASC

SELECT ANIMAL_ID, ANIMAL_TYPE, NAME FROM ANIMAL_INS
    WHERE SEX_UPON_INTAKE LIKE '%Intact%'
      AND ANIMAL_ID IN (SELECT ANIMAL_ID FROM ANIMAL_OUTS WHERE SEX_UPON_OUTCOME REGEXP ('Spayed|Neutered'))
    ORDER BY ANIMAL_ID ASC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. JOIN :&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1687756037989&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ~~ FROM TABLE_A A (LEFT|생략(INNER)|RIGHT|FULL) JOIN TABLE_B B ON A.KEY=B.KEY&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. LIKE&lt;/b&gt; : 특정 문자 포함되어 있는지 검색하기&lt;/p&gt;
&lt;pre id=&quot;code_1687757096104&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;% : 0개 이상의 문자
_ : 1개의 문자

WHERE 컬럼명 LIKE '값%' : 값으로 시작하는 경우만
WHERE 컬럼명 LIKE '%값' : 값으로 끝나는 경우만
WHERE 컬럼명 LIKE '%값%' : 값이 들어가는(포함되는) 경우 전체

WHERE 컬럼명 LIKE '% 값 %' : 앞 뒤 공백까지 포함해서 검색하므로 주의 !! 공백 제거 원할 경우 TRIM 사용하기

WHERE 컬럼명 LIKE 'm_ri_' : 5개의 글자이면서, 1.3.4번째 문자열이 m.r.i이고, 2.5번째 문자열은 어떤 문자열이라도 허용함
ㄴ ex. maria, mvriz, mqrip, m9ri8&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1687757656938&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- 만약 검색하려는 문자열이 WILDCARD 인 _이거나 % 인 경우에는?
 : WILDCARD인 _ % 앞에 \(역슬레쉬)를 넣어주면 된다 !
 
WHERE 컬럼명 LIKE '%\%%' : %(퍼센트) 표기가 들어있는 데이터들을 모두 불러오는 쿼리&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. REGEXP&lt;/b&gt; : LIKE 여러개 OR로 검색하기 (LIKE IN 같은 느낌)&lt;/p&gt;
&lt;pre id=&quot;code_1687756287217&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WHERE 컬럼명 REGEXP ('문자열1|문자열2|문자열3')
ㄴ 괄호는 생략 가능

= WHERE 컬럼명 LIKE '%문자열1%'
    OR 컬럼명 LIKE '%문자열2%'
    OR 컬럼명 LIKE '%문자열3%'&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[2] 서브쿼리 다중 조건, IN절, GROUP BY, &lt;u&gt;WHERE vs. HAVING&lt;/u&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687842698817&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/131116

# FOOD_PRODUCT 테이블에서 식품분류별로 가격이 제일 비싼 식품의 분류, 가격, 이름을 조회하는 SQL문을 작성해주세요.
# 이때 식품분류가 '과자', '국', '김치', '식용유'인 경우만 출력시켜 주시고 결과는 식품 가격을 기준으로 내림차순 정렬해주세요.
SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME FROM FOOD_PRODUCT
    WHERE (CATEGORY, PRICE) IN (SELECT CATEGORY, MAX(PRICE) FROM FOOD_PRODUCT WHERE CATEGORY IN ('과자', '국', '김치', '식용유') GROUP BY CATEGORY)
    ORDER BY MAX_PRICE DESC

SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME FROM FOOD_PRODUCT
    WHERE (CATEGORY, PRICE) IN (SELECT CATEGORY, MAX(PRICE) FROM FOOD_PRODUCT GROUP BY CATEGORY HAVING CATEGORY IN ('과자', '국', '김치', '식용유'))
    ORDER BY MAX_PRICE DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;서브쿼리 다중 조건 방법&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1687842794468&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM 테이블명 WHERE (컬럼1, 컬럼2) IN (SELECT 서브쿼리_컬럼1, 서브쿼리_컬럼2 FROM 서브쿼리_테이블);&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;GROUP BY 할 때, WHERE과 HAVING의 성능 차이&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 두 쿼리 모두 같은 검색 결과를 반환하며, 두개 모두 정답이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 쿼리의 차이점은 특정 CATEGORY만 뽑을 때, &lt;u&gt;WHERE절로 먼저 필요한 행만 뽑은 뒤 그룹핑할 것이냐, 그룹핑을 한 뒤 조건에 맞는 그룹만 뽑을 것이냐의 차이&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;결론&lt;/span&gt;부터 말하자면, &lt;b&gt;WHERE+GROUP BY가 GROUP BY+HAVING보다 성능이 좋다 !!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WHERE절에 의해 그룹화 과정에 불필요한 행을 미리 제외한 후에 GROUP BY절을 실행하면 내부정렬에 필요한 행의 수를 줄여주므로 효율적이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, HAVING을 사용할 경우 GROUP BY절에 의해 전체 행 집합을 먼저 정렬한 후에 HAVING절을 적용하여 조건에 맞는 그룹만 가져오는 방식이므로 비효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 위와 같이 &lt;u&gt;같은 내용의 조건&lt;/u&gt;이라면, &lt;u&gt;WHERE+GROUP BY를 사용&lt;/u&gt;하도록 하자 !&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IN절&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1687843974017&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;WHERE 일치하길 원하는 컬럼명 IN (조건1, 조건2, 조건3, ....)
WHERE 일치하지 않길 원하는 컬럼명 NOT IN (조건1, 조건2, 조건3, .....)

WHERE 일치하길 원하는 컬럼명 IN (조건) : 다중 조건이 아니여도 가능함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 조건들을&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt; OR 관계로 묶어 검색함 (IN 연산자가 OR 연산자 보다 실행 속도가 빠름 !)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;- &lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;값은 콤마( , )로 구분하여 괄호 내에 묶으며, 이 값 중에서 하나 이상과 일치하면 조건에 맞는 것으로 평가된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[3] JOIN + GROUP BY, SUM 함수&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687931179938&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/131117

# FOOD_PRODUCT와 FOOD_ORDER 테이블에서 생산일자가 2022년 5월인 식품들의 식품 ID, 식품 이름, 총매출을 조회하는 SQL문을 작성해주세요.
# 이때 결과는 총매출을 기준으로 내림차순 정렬해주시고 총매출이 같다면 식품 ID를 기준으로 오름차순 정렬해주세요.
SELECT P.PRODUCT_ID, P.PRODUCT_NAME, P.PRICE*O.SUM TOTAL_SALES FROM FOOD_PRODUCT P JOIN
    (SELECT PRODUCT_ID, SUM(AMOUNT) SUM FROM FOOD_ORDER WHERE DATE_FORMAT(PRODUCE_DATE, &quot;%Y%m&quot;)='202205' GROUP BY PRODUCT_ID) O ON P.PRODUCT_ID=O.PRODUCT_ID
    ORDER BY TOTAL_SALES DESC, PRODUCT_ID ASC

SELECT P.PRODUCT_ID, P.PRODUCT_NAME, P.PRICE*SUM(O.AMOUNT) TOTAL_SALES FROM FOOD_PRODUCT P JOIN FOOD_ORDER O ON P.PRODUCT_ID=O.PRODUCT_ID
    WHERE DATE_FORMAT(O.PRODUCE_DATE, &quot;%Y%m&quot;)='202205'
    GROUP BY P.PRODUCT_ID
    ORDER BY TOTAL_SALES DESC, PRODUCT_ID ASC

SELECT P.PRODUCT_ID, P.PRODUCT_NAME, SUM(O.AMOUNT*P.PRICE) TOTAL_SALES FROM FOOD_PRODUCT P JOIN FOOD_ORDER O ON P.PRODUCT_ID=O.PRODUCT_ID
    WHERE DATE_FORMAT(O.PRODUCE_DATE, &quot;%Y%m&quot;)='202205'
    GROUP BY P.PRODUCT_ID
    ORDER BY TOTAL_SALES DESC, PRODUCT_ID ASC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[4] ROUND, AVG 함수&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687998076101&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/131118

# REST_INFO와 REST_REVIEW 테이블에서 서울에 위치한 식당들의 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요.
# 이때 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 결과는 평균점수를 기준으로 내림차순 정렬해주시고, 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요.
SELECT I.REST_ID, I.REST_NAME, I.FOOD_TYPE, I.FAVORITES, I.ADDRESS, ROUND(AVG(R.REVIEW_SCORE), 2) SCORE FROM REST_INFO I
    JOIN REST_REVIEW R ON I.REST_ID=R.REST_ID
    WHERE I.ADDRESS LIKE '서울%'
    GROUP BY I.REST_ID
    ORDER BY SCORE DESC, I.FAVORITES DESC

SELECT I.REST_ID, I.REST_NAME, I.FOOD_TYPE, I.FAVORITES, I.ADDRESS, R.SCORE FROM REST_INFO I
    JOIN (SELECT REST_ID, ROUND(AVG(REVIEW_SCORE), 2) SCORE FROM REST_REVIEW GROUP BY REST_ID) R ON I.REST_ID=R.REST_ID
    WHERE I.ADDRESS LIKE '서울%'
    ORDER BY R.SCORE DESC, I.FAVORITES DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[ 숫자 함수 ]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;ROUND(숫자, 반올림할 자릿수)&lt;/b&gt; : 숫자를 반올림할 자릿수+1 자릿수에서 &lt;b&gt;반올림&lt;/b&gt; &lt;br /&gt;2. &lt;b&gt;TRUNCATE(숫자, 버릴 자릿수)&lt;/b&gt; : 숫자를 버릴 자릿수 아래로 &lt;b&gt;버림&lt;/b&gt; (※ 반드시 버릴 자릿수를 명시해 주어야 함)&lt;/p&gt;
&lt;pre id=&quot;code_1687998553417&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT ROUND(3456.1234567) FROM DUAL // 3456
SELECT ROUND(3456.1234567 ,1) FROM DUAL // 3456.1
SELECT ROUND(3456.1234567 ,4) FROM DUAL // 3456.1235
SELECT ROUND(3456.1234567 ,-1) FROM DUAL // 3460
SELECT ROUND(3456.1234567 ,-2) FROM DUAL // 3500

SELECT TRUNCATE(3456.1234567 ,1) FROM DUAL // 3456.1
SELECT TRUNCATE(3456.1234567 ,4) FROM DUAL // 3456.1234
SELECT TRUNCATE(3456.1234567 ,-1) FROM DUAL // 3450
SELECT TRUNCATE(3456.1234567 ,-2) FROM DUAL // 3400&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;CEIL(숫자), CEILING(숫자)&lt;/b&gt; : &lt;b&gt;올림&lt;/b&gt; - 정수값 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;FLOOR(숫자)&lt;/b&gt; : &lt;b&gt;내림/버림&lt;/b&gt; - 정수값 출력&lt;/p&gt;
&lt;pre id=&quot;code_1687998960507&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT CEIL(21.35) // 22 
SELECT CEIL(21.9) // 22

SELECT FLOOR(21.35) // 21 
SELECT FLOOR(21.9) // 21&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;b&gt;ABS(숫자)&lt;/b&gt; : &lt;b&gt;절대값&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. &lt;b&gt;POW(A, B), POWER(A, B)&lt;/b&gt; : &lt;b&gt;A의 B승&lt;/b&gt;(A를 B만큼 제곱)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. &lt;b&gt;SQRT(숫자)&lt;/b&gt; : &lt;b&gt;제곱근&lt;/b&gt;&amp;nbsp; &amp;nbsp;ex. SQRT(16)=POWER(16, 1/2)=4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. &lt;b&gt;MOD(분자, 분모)&lt;/b&gt; : 분자를 분모로 나눈 &lt;b&gt;나머지&lt;/b&gt; 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. &lt;b&gt;GREATEST(숫자1, 숫자2, ...)&lt;/b&gt; : 주어진 숫자 중에 &lt;b&gt;가장 큰 값&lt;/b&gt;을 반환, (괄호 안에서) 가장 큰 값&lt;br /&gt;10. &lt;b&gt;LEAST(숫자1, 숫자2, ...)&lt;/b&gt; : 주어진 숫자 중에 &lt;b&gt;가장 작은 값&lt;/b&gt;을 반환, (괄호 안에서) 가장 작은 값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;( != MAX, MIN : 여러 행들 중에서 최댓값과 최솟값을 구함 )&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688000648729&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT
  OrderDetailID, ProductID, Quantity,
  GREATEST(OrderDetailID, ProductID, Quantity),
  LEAST(OrderDetailID, ProductID, Quantity)
FROM OrderDetails;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;[ 집계 함수(그룹 함수) ] : 주로 GROUP BY와 함께 사용 !&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start; border-collapse: collapse; width: 67.6744%; height: 132px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666; width: 37.1134%;&quot;&gt;&lt;b&gt;MAX(컬럼)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666; width: 62.7148%;&quot;&gt;해당 컬럼 값들 중 &lt;b&gt;가장 큰 값 (최댓값)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666; width: 37.1134%;&quot;&gt;&lt;b&gt;MIN(컬럼)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666; width: 62.7148%;&quot;&gt;해당 컬럼 값들 중 &lt;b&gt;가장 작은 값 (최솟값)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666; width: 37.1134%;&quot;&gt;&lt;b&gt;COUNT(컬럼)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666; width: 62.7148%;&quot;&gt;해당 컬럼의 데이터 &lt;b&gt;갯수&lt;/b&gt; (&lt;b&gt;&lt;u&gt;NULL값 제외&lt;/u&gt;&lt;/b&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666; width: 37.1134%;&quot;&gt;&lt;b&gt;SUM(컬럼)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666; width: 62.7148%;&quot;&gt;해당 컬럼 값들의 &lt;b&gt;총합&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666; width: 37.1134%;&quot;&gt;&lt;b&gt;AVG(컬럼)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666; width: 62.7148%;&quot;&gt;해당 컬럼 값들의 &lt;b&gt;평균 값&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[5] COUNT+DISTINCT, GROUP BY 3번&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1688108912980&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/131532

# USER_INFO 테이블과 ONLINE_SALE 테이블에서 년, 월, 성별 별로 상품을 구매한 회원수를 집계하는 SQL문을 작성해주세요.
# 결과는 년, 월, 성별을 기준으로 오름차순 정렬해주세요. 이때, 성별 정보가 없는 경우 결과에서 제외해주세요.
SELECT YEAR(S.SALES_DATE) YEAR, MONTH(S.SALES_DATE) MONTH, U.GENDER, COUNT(DISTINCT S.USER_ID) USERS FROM ONLINE_SALE S
    JOIN USER_INFO U ON S.USER_ID=U.USER_ID
    WHERE U.GENDER IS NOT NULL
    GROUP BY YEAR(S.SALES_DATE), MONTH(S.SALES_DATE), U.GENDER
    ORDER BY YEAR ASC, MONTH ASC, GENDER ASC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;COUNT&lt;/b&gt; : 데이블에 컬럼의 데이터 &lt;b&gt;개수&lt;/b&gt; 반환 (&lt;u&gt;NULL인 데이터는 제외&lt;/u&gt;하고 카운팅, &lt;u&gt;중복 제거 X&lt;/u&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ COUNT(*) 일 경우에는, NULL 값이 존재하는 행도 포함한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;DISTINCT&lt;/b&gt; : &lt;b&gt;중복&lt;/b&gt;을 &lt;b&gt;제거&lt;/b&gt;해줌.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ex. DISTINCT 컬럼, SELECT&amp;nbsp;DISTINCT&amp;nbsp;컬럼&amp;nbsp;FROM&amp;nbsp;테이블&amp;nbsp;WHERE&amp;nbsp;조건식;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;COUNT+DISTINCT&lt;/b&gt; : &lt;u&gt;NULL 값이 아닌&lt;/u&gt; 데이터 중에서 &lt;b&gt;중복을 제거한 개수&lt;/b&gt;를 반환&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ex. COUNT(DISTINCT 컬럼), COUNT(DISTINCT S.USER_ID)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DB : MySQL | Oracle | MyBatis</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/119</guid>
      <comments>https://maemae22.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 26 Jun 2023 14:35:23 +0900</pubDate>
    </item>
    <item>
      <title>MySQL 문법 정리 (w. 프로그래머스 SQL Lv. 3 문제 풀이)</title>
      <link>https://maemae22.tistory.com/118</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;프로그래머스 SQL 문제를 풀면서 헷갈렸던 문법들을 정리해보자.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 전에, SQL 구문(문법) 순서에 대해서 알아보자&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[SQL 구문의 순서]&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687518162784&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT 컬럼명 --------------------- (5)
FROM 테이블명 ------------------- (1)
WHERE 테이블 조건 --------------- (2)
GROUP BY 컬럼명 -------------------- (3)
HAVING 그룹 조건 ----------------- (4)
ORDER BY 컬럼명 -------------------- (6)&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[실제 원하는 데이터를 찾는 과정]&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #0900ff;&quot;&gt;FROM&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;: SQL은 구문이 들어오면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;테이블을 가장 먼저 확인&lt;/b&gt;한다. 테이블이 없는데 다른 것들을 먼저 조회할 수 없으니까.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #0900ff;&quot;&gt;&lt;b&gt;WHERE&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;: 테이블명을 확인했으니,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;테이블에서 주어진 조건에 맞는 데이터들을&amp;nbsp;추출&lt;/b&gt;해준다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #0900ff;&quot;&gt;GROUP BY&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 조건에 맞는 데이터가 추출되었으니,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;공통적인 데이터들끼리 묶어 그룹&lt;/b&gt;을 만들어준다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;4.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #0900ff;&quot;&gt;HAVING&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 공통적인 데이터들이 묶여진 그룹 중,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;주어진 조건에 맞는 그룹들을 추출&lt;/b&gt;한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;5.&amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #0900ff;&quot;&gt;SELECT&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 최종적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;추출된 데이터들을 조회&lt;/b&gt;한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;6.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #0900ff;&quot;&gt;ORDER BY&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 추출된 데이터들을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;정렬&lt;/b&gt;한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;* SELECT 다음으로 오는 구문은 ORDER BY 뿐이므로, &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;SELECT 에서 만들어진 Alias 는 ORDER BY 구문에서만 사용 가능하다.&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687518441106&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;추후 추가 : EXISTS, TIMESTAMPDIFF, TRIM, REPLACE, ALL, ANY 등&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[1] WHERE 절에서 두가지 조건으로 검색 + 서브쿼리 사용 + IN절&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687500529444&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/131123

# REST_INFO 테이블에서 음식종류별로 즐겨찾기수가 가장 많은 식당의 음식 종류, ID, 식당 이름, 즐겨찾기수를 조회하는 SQL문을 작성해주세요.
# 이때 결과는 음식 종류를 기준으로 내림차순 정렬해주세요.
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES FROM REST_INFO
    WHERE (FOOD_TYPE, FAVORITES) IN (SELECT FOOD_TYPE, MAX(FAVORITES) FROM REST_INFO GROUP BY FOOD_TYPE)
    ORDER BY FOOD_TYPE DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;+ GROUP BY 절이 있는 구문에서 SELECT절에는 &lt;u&gt;GROUP BY의 기준이 되는 컬럼 또는 집계함수&lt;/u&gt;만 들어갈 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( 다른 것을 넣어도 MySQL은 에러를 발생하지 않는다... 그래서 잘못된 부분을 잡기 더 어려울 수 있으니 주의하기 )&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[2] CONCAT, CONCAT_WS, SUBSTR, LEFT, RIGHT, COUNT 함수&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687501223917&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/164670

# USED_GOODS_BOARD와 USED_GOODS_USER 테이블에서 중고 거래 게시물을 3건 이상 등록한 사용자의
# 사용자 ID, 닉네임, 전체주소, 전화번호를 조회하는 SQL문을 작성해주세요.
# 이때, 전체 주소는 시, 도로명 주소, 상세 주소가 함께 출력되도록 해주시고, 전화번호의 경우 xxx-xxxx-xxxx 같은 형태로 하이픈 문자열(-)을 삽입하여 출력해주세요.
# 결과는 회원 ID를 기준으로 내림차순 정렬해주세요.
SELECT U.USER_ID, U.NICKNAME, CONCAT(U.CITY, &quot; &quot;, U.STREET_ADDRESS1, &quot; &quot;, U.STREET_ADDRESS2) AS 젼체주소,
       CONCAT(SUBSTR(TLNO, 1, 3), &quot;-&quot;, SUBSTR(TLNO, 4, 4), &quot;-&quot;, SUBSTR(TLNO, 8)) AS 전화번호 FROM USED_GOODS_USER U
       JOIN USED_GOODS_BOARD B ON U.USER_ID=B.WRITER_ID
       GROUP BY B.WRITER_ID HAVING COUNT(B.WRITER_ID)&amp;gt;=3
       ORDER BY U.USER_ID DESC

SELECT U.USER_ID, U.NICKNAME, CONCAT_WS(&quot; &quot;, U.CITY, U.STREET_ADDRESS1, U.STREET_ADDRESS2) AS 젼체주소,
       CONCAT_WS(&quot;-&quot;, LEFT(TLNO, 3), SUBSTR(TLNO, 4, 4), RIGHT(TLNO, 4)) AS 전화번호 FROM USED_GOODS_USER U
       JOIN USED_GOODS_BOARD B ON U.USER_ID=B.WRITER_ID
       GROUP BY B.WRITER_ID HAVING COUNT(B.WRITER_ID)&amp;gt;=3
       ORDER BY U.USER_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;table style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start; border-collapse: collapse; width: 100%; height: 40px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;CONCAT&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;(..., ..., ...)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;괄호 안의 문자열들을 이어붙임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;CONCAT_WS&lt;/b&gt;(S, &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;..., ..., ...&lt;/span&gt;&lt;/b&gt;)&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;괄호 안의 문자열들을 S로 이어붙임&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; letter-spacing: 0px;&quot;&gt;숫자가 끼어있어도 문자열로 변환되어 이어진다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;table style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;SUBSTR&lt;/b&gt;,&amp;nbsp;&lt;b&gt;SUBSTRING&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;주어진 값에 따라 문자열 자름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;LEFT&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;왼쪽부터 N글자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;RIGHT&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;오른쪽부터 N글자&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. SUBSTR(대상 문자열, 시작점(1부터 카운팅), 가져올 글자 수(생략일 경우 끝까지)) :&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 인수를 3개 받을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫번째 인수를 대상으로 두번째 인수부터 시작하여 세번째 인수의 수 만큼 왼쪽에서 오른쪽으로 센 후 뒤의 문자를 잘라서 가져온다.&lt;/li&gt;
&lt;li&gt;첫번째 인수 : 대상 문자열 / 두번째 인수 : 시작점(&lt;u&gt;1부터 카운팅&lt;/u&gt;) / 세번째 인수 : 가져올 글자 수 (생략일 경우 시작점부터 끝까지 가져옴)&lt;/li&gt;
&lt;li&gt;두번째 인수가 음수인 경우 문자의 뒤(오른쪽) 끝에서부터 셈을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. LEFT(문자열, 개수) :&lt;/b&gt; 문자열 왼쪽에서부터 두번째 인자에 적힌 수 만큼 글자를 가져온다. &lt;br /&gt;&lt;b&gt;3. RIGHT(문자열, 개수) :&lt;/b&gt; 문자열 오른쪽에서부터 두번째 인자에 적힌 수 만큼 글자를 가져온다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;table style=&quot;background-color: #ffffff; color: #5c5c5c; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;COUNT&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;갯수 (&lt;u&gt;NULL값 제외&lt;/u&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블에 컬럼의 데이터 개수를 가져옴 (NULL인 데이터는 제외)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 행 개수를 가져올 때는 컬럼명 대신 * 사용 가능&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[3] (⭐어려움⭐) MAX, SUM, IF, BETWEEN 함수 (+ CASE, IFNULL 함수)&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; - 단순 함수 문법이 아닌, 풀이 방법을 잘 기억해둘 것 ! &lt;u&gt;(좋은 방법은 아님, 좀 억지 풀이법 .... 설명은 밑에)&lt;/u&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687515258272&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/157340

# CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 2022년 10월 16일에 대여 중인 자동차인 경우 '대여중' 이라고 표시하고, 대여 중이지 않은 자동차인 경우 '대여 가능'을 표시하는 컬럼(컬럼명: AVAILABILITY)을 추가하여 자동차 ID와 AVAILABILITY 리스트를 출력하는 SQL문을 작성해주세요.
# 이때 반납 날짜가 2022년 10월 16일인 경우에도 '대여중'으로 표시해주시고 결과는 자동차 ID를 기준으로 내림차순 정렬해주세요.
SELECT CAR_ID, MAX(IF(START_DATE&amp;lt;='2022-10-16' AND '2022-10-16'&amp;lt;=END_DATE, '대여중', '대여 가능')) AS AVAILABILITY
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY GROUP BY CAR_ID ORDER BY CAR_ID DESC

SELECT CAR_ID, IF(SUM(IF('2022-10-16' BETWEEN START_DATE AND END_DATE, 1, 0))=0, '대여 가능', '대여중') AS AVAILABILITY
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY GROUP BY CAR_ID ORDER BY CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- (추가) 더 좋은 방법 : LEFT JOIN 사용&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687526327290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT DISTINCT H.CAR_ID, IF(R.CAR_ID IS NULL, '대여 가능', '대여중') AS AVAILABILITY 
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H 
LEFT JOIN (SELECT DISTINCT CAR_ID FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE) R ON H.CAR_ID=R.CAR_ID 
ORDER BY CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- (추추가) &lt;span style=&quot;background-color: #f3c000;&quot;&gt;가장 좋은 방법&lt;/span&gt; : IN절, DISTINCT 사용 / GROUP BY 사용x&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687526515455&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT DISTINCT CAR_ID, 
IF(CAR_ID IN (SELECT DISTINCT CAR_ID FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE), '대여중', '대여 가능') AS AVAILABILTIY 
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY 
ORDER BY CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 문법 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;MAX()&lt;/b&gt; : 최댓값 반환. 괄호 안에 컬럼명 등이 들어갈 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;SUM()&lt;/b&gt; : 총합 반환. 괄호 안에 컬럼명 등이 들어갈 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. IF문 : &lt;b&gt;IF(조건식, 조건식이 참일 때 값, 조건식이 거짓일 때 값)&lt;/b&gt; &lt;s&gt;AS ALIAS&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;CASE문&lt;/b&gt; :&lt;/p&gt;
&lt;pre id=&quot;code_1687518178086&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CASE 
    WHEN 조건1 THEN '조건1 참일 경우 반환값'
    WHEN 조건2 THEN '조건2 참일 경우 반환값'
    ELSE '충족되는 조건 없을 때 반환값'
END AS ALIAS&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;b&gt;IFNULL문&lt;/b&gt; : IFNULL(컬럼(데이터), '인수1의 데이터 값이 NULL일 경우 출력할 값')&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 컬럼이 NULL이 아니면 그대로 출력하고, NULL일 경우 2번째 인자에 적은 값을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. &lt;b&gt;BETWEEN&lt;/b&gt; : 'WHERE 컬럼명 BETWEEN 시작범위 AND 종료범위'과 같이 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;- '시작범위&amp;lt;=(컬럼)&amp;lt;= 종료범위'로 검색, 시작범위와 종료범위를 모두 포함한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 첫번째 풀이 설명&lt;/p&gt;
&lt;pre id=&quot;code_1687518120538&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MAX(IF(START_DATE&amp;lt;='2022-10-16' AND '2022-10-16'&amp;lt;=END_DATE, '대여중', '대여 가능'))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IF절을 통해 대여 중인 경우 '대여중', 대여 중이 아닌 경우 '대여 가능' 이라고 출력될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 문제에서 요구하는 '대여 가능'이 되려면, 해당 CAR_ID의 모든 값이 '대여 가능'이여야 '대여 가능' 이라고 판단할 수 있다. 만약 IF절에서 나온 값에 '대여중'과 '대여 가능'이 함께 있다면 이 자동차는 '대여중'이라고 출력되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(다시 말해, '대여 가능' 상태라면 모든 데이터가 '대여 가능'일 경우에만 가능하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1687515729104&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT IF('대여중'&amp;gt;'대여 가능', 1, 0);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 검색해보면 1이 나온다. 즉, '대여중 &amp;gt; 대여 가능'이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 IF문에서 나온 값을 MAX() 함수로 처리하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 데이터가 '대여중'이면 -&amp;gt; '대여중'이,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 데이터가 '대여 가능'이면 -&amp;gt; '대여 가능'이,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'대여중'과 '대여 가능'이 함께 존재하면 -&amp;gt; '대여중' 이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 IF와 MAX 함수를 같이 사용하여 문제에서 원하는 최종 답을 출력할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 두번째 풀이 설명&lt;/p&gt;
&lt;pre id=&quot;code_1687517790306&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;IF(SUM(IF('2022-10-16' BETWEEN START_DATE AND END_DATE, 1, 0))=0, '대여 가능', '대여중')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안쪽의 IF절 'IF('2022-10-16' BETWEEN START_DATE AND END_DATE, 1, 0)' 을 통해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대여중일 경우 1, 대여 중이 아닐 경우 0으로 표시된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것들을 SUM 함수로 모두 더했을 때, 값이 0이라면(=모든 데이터가 대여 중이 아닐 경우, 0+0+0+0 ..) 대여 가능 상태라고 판단할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다시 한번 IF절로 감싸서, SUM절이 0일 경우 '대여 가능'으로 표시하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대여중인 자동차가 있어 SUM절이 0이 아닐 경우에는 '대여중'으로 표시하여 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;( + &lt;u&gt;IF문 안에서 숫자 비교&lt;/u&gt; 할 시, &lt;/b&gt;== 가 아닌&lt;b&gt;, '&lt;u&gt;=' 을 사용&lt;/u&gt;하면&amp;nbsp; 된다)&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[4] 서브쿼리, LIMIT&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687682499037&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/164671

# USED_GOODS_BOARD와 USED_GOODS_FILE 테이블에서 조회수가 가장 높은 중고거래 게시물에 대한 첨부파일 경로를 조회하는 SQL문을 작성해주세요.
# 첨부파일 경로는 FILE ID를 기준으로 내림차순 정렬해주세요.
# 기본적인 파일경로는 /home/grep/src/ 이며, 게시글 ID를 기준으로 디렉토리가 구분되고, 파일이름은 파일 ID, 파일 이름, 파일 확장자로 구성되도록 출력해주세요.
# 조회수가 가장 높은 게시물은 하나만 존재합니다.
SELECT CONCAT(&quot;/home/grep/src/&quot;, BOARD_ID, &quot;/&quot;, FILE_ID, FILE_NAME, FILE_EXT) AS FILE_PATH FROM USED_GOODS_FILE
    WHERE BOARD_ID=(SELECT BOARD_ID FROM USED_GOODS_BOARD WHERE VIEWS=(SELECT MAX(VIEWS) FROM USED_GOODS_BOARD))
    ORDER BY FILE_ID DESC

SELECT CONCAT(&quot;/home/grep/src/&quot;, BOARD_ID, &quot;/&quot;, FILE_ID, FILE_NAME, FILE_EXT) AS FILE_PATH FROM USED_GOODS_FILE
    WHERE BOARD_ID=(SELECT BOARD_ID FROM USED_GOODS_BOARD ORDER BY VIEWS DESC LIMIT 1)
    ORDER BY FILE_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LIMIT n&lt;/b&gt; : n개의 데이터만 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LIMIT s, n&lt;/b&gt; : (s+1)번째 데이터부터 n개의 데이터 가져옴 (&lt;u&gt;offset(첫번째 파라미터)은 0부터 카운팅한다&lt;/u&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex. LIMIT 10 : 10개의 데이터 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex. LIMIT 10, 5 : 11번째 데이터부터 5개 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex. LIMIT 0, 3 : 1~3번째 데이터 가져옴 (3개)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[5] GROUP BY 2개 이상, MONTH, DATE_FORMAT 함수, IN절&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1687696581034&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://school.programmers.co.kr/learn/courses/30/lessons/151139

# CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서
# 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요.
# 결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해주세요.
# 특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해주세요.
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(CAR_ID) AS RECORDS FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE CAR_ID IN (SELECT CAR_ID FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
                    WHERE DATE_FORMAT(START_DATE, &quot;%Y-%m&quot;) BETWEEN '2022-08' AND '2022-10' GROUP BY CAR_ID HAVING COUNT(CAR_ID)&amp;gt;=5)
    AND DATE_FORMAT(START_DATE, &quot;%Y-%m&quot;) BETWEEN '2022-08' AND '2022-10'
    GROUP BY MONTH(START_DATE), CAR_ID
    HAVING COUNT(CAR_ID)&amp;gt;0
    ORDER BY MONTH ASC, CAR_ID DESC&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;리턴값 : int형&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MONTH(날짜)&lt;/b&gt; : 해당 날짜가 몇 월인지 리턴. 1~12 사이.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;YEAR(날짜)&lt;/b&gt; : 년도 리턴. 1000~9999 사이.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HOUR(시간)&lt;/b&gt; : 시간 리턴. 0~23 사이.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MINUTE(시간)&lt;/b&gt; : 분 리턴. 0~59 사이.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SECOND(시간)&lt;/b&gt; : 초 리턴. 0~59 사이.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DATE_FORMAT(날짜, format)&lt;/b&gt; : format에 설정한 형식대로 날짜를 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;String&lt;/span&gt;으로 만들어 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ format 예시 ]&lt;/b&gt;&lt;br /&gt;%Y : 4자리&amp;nbsp;년도 &lt;br /&gt;%y : 2자리&amp;nbsp;년도 &lt;br /&gt;%m : 월(01..12)&lt;br /&gt;%c : 월(1..12)&lt;br /&gt;%d : 일(00..31) &lt;br /&gt;%e : 일(0..31)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex. '2023-05-21' 처럼 표현하고 싶다면 -&amp;gt; &lt;b&gt;DATE_FORMAT(날짜, &quot;%Y-%m-%d&quot;)&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;DATE_FORMAT(START_DATE, &quot;%c&quot;) 와 MONTH(START_DATE)의 차이&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 문제에서 8, 9, 10을 오름차순으로 정렬해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ORDER BY MONTH(START_DATE) ASC -&amp;gt; 8. 9. 10으로 정렬되지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ORDER BY DATE_FORMAT(START_DATE, &quot;%c&quot;) ASC -&amp;gt; &lt;u&gt;10. 8. 9 로 정렬된다 ..&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. 8. 9는 오름차순도 내림차순도 아니다. 얼핏 보면 &quot;%c&quot;가 월을 1, 5, 12와 같은 형식으로 반환하기 때문에 똑같아 보여서 이 부분에서 실수하여 문제를 틀리는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하면 &lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;리턴 타입의 차이&lt;/span&gt;&lt;/b&gt;로 인해 이러한 결과가 발생한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MONTH() 함수는 리턴 타입이 int이기 때문에, 8 9 10을 오름차순 정렬하였을 경우 원하는대로 8 9 10이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 DATE_FORMAT()은 입력한 날짜를 사용자가 입력한 format에 맞춰 &lt;u&gt;String으로 반환&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;8&quot;, &quot;9&quot;, &quot;10&quot;의 문자열 정렬인 경우, 맨 처음 숫자가 1인 &quot;10&quot;이 가장 먼저 정렬되고, 나머지 8 9 가 정렬되어 10 8 9로 정렬된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[*] MySQL 문법 정리되어 있는 유용한 글&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.yalco.kr/lectures/sql/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.yalco.kr/lectures/sql/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687502645506&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;MySQL&quot; data-og-description=&quot;어려운 프로그래밍 개념들을 쉽게 설명해주는 유튜브 채널 '얄팍한 코딩사전'. 영상에서 다 알려주지 못한 정보들이나 자주 묻는 질문들의 답변들, 예제 코드들을 얄코에서 확인하세요!&quot; data-og-host=&quot;www.yalco.kr&quot; data-og-source-url=&quot;https://www.yalco.kr/lectures/sql/&quot; data-og-url=&quot;https://www.yalco.kr/lectures/sql/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8WO4Y/hyS5FVNIqO/Bd83HHbaWxDGd5unhR7lyk/img.png?width=1120&amp;amp;height=300&amp;amp;face=0_0_1120_300&quot;&gt;&lt;a href=&quot;https://www.yalco.kr/lectures/sql/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.yalco.kr/lectures/sql/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8WO4Y/hyS5FVNIqO/Bd83HHbaWxDGd5unhR7lyk/img.png?width=1120&amp;amp;height=300&amp;amp;face=0_0_1120_300');&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;MySQL&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.yalco.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@max-sum/MySQL-%EB%AC%B8%EB%B2%952.-%ED%95%A8%EC%88%98-%EA%B7%B8%EB%A3%B9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@max-sum/MySQL-%EB%AC%B8%EB%B2%952.-%ED%95%A8%EC%88%98-%EA%B7%B8%EB%A3%B9&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687501451700&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;MySQL | 문법_2. 숫자와 문자열 관련 함수&quot; data-og-description=&quot;MySQL과 함수 친구들&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@max-sum/MySQL-%EB%AC%B8%EB%B2%952.-%ED%95%A8%EC%88%98-%EA%B7%B8%EB%A3%B9&quot; data-og-url=&quot;https://velog.io/@max-sum/MySQL-문법2.-함수-그룹&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/basQO5/hyS5yWEynn/ShsTQYxP3mhMMKrIRzmo50/img.png?width=1200&amp;amp;height=514&amp;amp;face=0_0_1200_514,https://scrap.kakaocdn.net/dn/bfZfLA/hyS5Cksh11/3RJLk0FHbI7gUcKQNakFs1/img.png?width=1200&amp;amp;height=514&amp;amp;face=0_0_1200_514,https://scrap.kakaocdn.net/dn/bZuECU/hyS5DDEuom/ghTeWkOQAgku8vKGsZ7yb0/img.png?width=2266&amp;amp;height=564&amp;amp;face=0_0_2266_564&quot;&gt;&lt;a href=&quot;https://velog.io/@max-sum/MySQL-%EB%AC%B8%EB%B2%952.-%ED%95%A8%EC%88%98-%EA%B7%B8%EB%A3%B9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@max-sum/MySQL-%EB%AC%B8%EB%B2%952.-%ED%95%A8%EC%88%98-%EA%B7%B8%EB%A3%B9&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/basQO5/hyS5yWEynn/ShsTQYxP3mhMMKrIRzmo50/img.png?width=1200&amp;amp;height=514&amp;amp;face=0_0_1200_514,https://scrap.kakaocdn.net/dn/bfZfLA/hyS5Cksh11/3RJLk0FHbI7gUcKQNakFs1/img.png?width=1200&amp;amp;height=514&amp;amp;face=0_0_1200_514,https://scrap.kakaocdn.net/dn/bZuECU/hyS5DDEuom/ghTeWkOQAgku8vKGsZ7yb0/img.png?width=2266&amp;amp;height=564&amp;amp;face=0_0_2266_564');&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;MySQL | 문법_2. 숫자와 문자열 관련 함수&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;MySQL과 함수 친구들&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;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://extbrain.tistory.com/50&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://extbrain.tistory.com/50&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687502468386&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;[MySQL] 연산자 (Operator)&quot; data-og-description=&quot;▶MySQL 연산자 (Operator) ▶설명 MySQL 연산자는 특정 작업을 하기 위한 기호 또는 문자입니다. ▶비교 연산자 (관계 연산자) 설명비교 연산자는 주어진 좌우 값을 비교하는 연산자입니다. 연산자연&quot; data-og-host=&quot;extbrain.tistory.com&quot; data-og-source-url=&quot;https://extbrain.tistory.com/50&quot; data-og-url=&quot;https://extbrain.tistory.com/50&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dGHcyS/hyS5D4KxIV/mkOxTq8Izk0luYBgang8p0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/FGmH0/hyS5Gf7rjg/PXUifGAdj1TejPGHDs4oTK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://extbrain.tistory.com/50&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://extbrain.tistory.com/50&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dGHcyS/hyS5D4KxIV/mkOxTq8Izk0luYBgang8p0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/FGmH0/hyS5Gf7rjg/PXUifGAdj1TejPGHDs4oTK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;[MySQL] 연산자 (Operator)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;▶MySQL 연산자 (Operator) ▶설명 MySQL 연산자는 특정 작업을 하기 위한 기호 또는 문자입니다. ▶비교 연산자 (관계 연산자) 설명비교 연산자는 주어진 좌우 값을 비교하는 연산자입니다. 연산자연&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;extbrain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://redcow77.tistory.com/260&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://redcow77.tistory.com/260&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687502484788&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;[Mysql] Mysql 조건문 - IF 문, CASE 문&quot; data-og-description=&quot;Mysql의 IF ~ Else 조건문 (Mysql의 IF 문은 엑셀에서의 IF 함수와 동일합니다.) if ( 조건문, 참일때 값, 거짓일때 값) SELECT IF(required, '필수' '선택') AS '필수여부' FROM TABLE SELECT A.seq, IF(A.seq&quot; data-og-host=&quot;redcow77.tistory.com&quot; data-og-source-url=&quot;https://redcow77.tistory.com/260&quot; data-og-url=&quot;https://redcow77.tistory.com/260&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/JUB7o/hyS5AAaZVU/3Fa0ItF0XkkQsryA2hVMZk/img.jpg?width=395&amp;amp;height=395&amp;amp;face=0_0_395_395,https://scrap.kakaocdn.net/dn/bRTR60/hyS5wR6rqU/KCVi2FxGzGYMlniSkkxCqk/img.jpg?width=395&amp;amp;height=395&amp;amp;face=0_0_395_395,https://scrap.kakaocdn.net/dn/ipCO5/hyS5tHP5Gi/RwoCv83fANJa4BW39Ow2nk/img.jpg?width=497&amp;amp;height=603&amp;amp;face=206_196_314_314&quot;&gt;&lt;a href=&quot;https://redcow77.tistory.com/260&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://redcow77.tistory.com/260&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/JUB7o/hyS5AAaZVU/3Fa0ItF0XkkQsryA2hVMZk/img.jpg?width=395&amp;amp;height=395&amp;amp;face=0_0_395_395,https://scrap.kakaocdn.net/dn/bRTR60/hyS5wR6rqU/KCVi2FxGzGYMlniSkkxCqk/img.jpg?width=395&amp;amp;height=395&amp;amp;face=0_0_395_395,https://scrap.kakaocdn.net/dn/ipCO5/hyS5tHP5Gi/RwoCv83fANJa4BW39Ow2nk/img.jpg?width=497&amp;amp;height=603&amp;amp;face=206_196_314_314');&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;[Mysql] Mysql 조건문 - IF 문, CASE 문&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mysql의 IF ~ Else 조건문 (Mysql의 IF 문은 엑셀에서의 IF 함수와 동일합니다.) if ( 조건문, 참일때 값, 거짓일때 값) SELECT IF(required, '필수' '선택') AS '필수여부' FROM TABLE SELECT A.seq, IF(A.seq&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;redcow77.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@12aeun/SQL-mysql%EC%97%90%EC%84%9C-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@12aeun/SQL-mysql%EC%97%90%EC%84%9C-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687502507437&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] mysql 날짜 관련 함수 정리&quot; data-og-description=&quot;DATEDIFF() : 두 기간 사이의 일수 계산TIMEDIFF() : 두 기간 사이의 시간 계산PERIOD_DIFF() : 두 기간 사이의 개월 수 계산TIMESTAMPDIFF() : 두 기간 사이의 시간 계산두 기간 사이의 일수 계산 expr1 - expr2 (&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@12aeun/SQL-mysql%EC%97%90%EC%84%9C-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&quot; data-og-url=&quot;https://velog.io/@12aeun/SQL-mysql에서-날짜-시간-계산하기&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/r57Eq/hyS5A1fK40/IlKuZUkIC8BU0dsVlwNLK0/img.png?width=1536&amp;amp;height=804&amp;amp;face=0_0_1536_804,https://scrap.kakaocdn.net/dn/bHtDOH/hyS5DwUquS/2XfrjAM1cLkiTp7KNXHHD0/img.png?width=1536&amp;amp;height=804&amp;amp;face=0_0_1536_804,https://scrap.kakaocdn.net/dn/bt2s66/hyS5CEMc2I/8TrOBaiCM00GtqfwL9QofK/img.png?width=1536&amp;amp;height=804&amp;amp;face=0_0_1536_804&quot;&gt;&lt;a href=&quot;https://velog.io/@12aeun/SQL-mysql%EC%97%90%EC%84%9C-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@12aeun/SQL-mysql%EC%97%90%EC%84%9C-%EB%82%A0%EC%A7%9C-%EC%8B%9C%EA%B0%84-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/r57Eq/hyS5A1fK40/IlKuZUkIC8BU0dsVlwNLK0/img.png?width=1536&amp;amp;height=804&amp;amp;face=0_0_1536_804,https://scrap.kakaocdn.net/dn/bHtDOH/hyS5DwUquS/2XfrjAM1cLkiTp7KNXHHD0/img.png?width=1536&amp;amp;height=804&amp;amp;face=0_0_1536_804,https://scrap.kakaocdn.net/dn/bt2s66/hyS5CEMc2I/8TrOBaiCM00GtqfwL9QofK/img.png?width=1536&amp;amp;height=804&amp;amp;face=0_0_1536_804');&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] mysql 날짜 관련 함수 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DATEDIFF() : 두 기간 사이의 일수 계산TIMEDIFF() : 두 기간 사이의 시간 계산PERIOD_DIFF() : 두 기간 사이의 개월 수 계산TIMESTAMPDIFF() : 두 기간 사이의 시간 계산두 기간 사이의 일수 계산 expr1 - expr2 (&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;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codingspooning.tistory.com/entry/MySQL-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-SUBSTR-SUBSTRING&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codingspooning.tistory.com/entry/MySQL-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-SUBSTR-SUBSTRING&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687502528900&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;[MySQL] 문자열 자르기 (SUBSTR, SUBSTRING)&quot; data-og-description=&quot;안녕하세요. 오늘은 MySQL에서 간단하게 문자열을 추출하거나 자를 때 사용하는 함수에 대해 알아보겠습니다. SQL 문자열 추출 함수 (SUBSTR, SUBSTRING) ▣ 문자열 자르기 함수 종류 RDBMS Function Oracle SUB&quot; data-og-host=&quot;codingspooning.tistory.com&quot; data-og-source-url=&quot;https://codingspooning.tistory.com/entry/MySQL-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-SUBSTR-SUBSTRING&quot; data-og-url=&quot;https://codingspooning.tistory.com/entry/MySQL-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-SUBSTR-SUBSTRING&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btiTLW/hyS5xcps7l/VqEuIBiK4U7ku3C8YFuau1/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/VlgtA/hyS5z2lJBW/ThQWOAcGXtOXro8wcUVhr0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/86U6t/hyS5BZ9Myr/e9mhWpritWLbiINF9FJiEK/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://codingspooning.tistory.com/entry/MySQL-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-SUBSTR-SUBSTRING&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingspooning.tistory.com/entry/MySQL-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-SUBSTR-SUBSTRING&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btiTLW/hyS5xcps7l/VqEuIBiK4U7ku3C8YFuau1/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/VlgtA/hyS5z2lJBW/ThQWOAcGXtOXro8wcUVhr0/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200,https://scrap.kakaocdn.net/dn/86U6t/hyS5BZ9Myr/e9mhWpritWLbiINF9FJiEK/img.png?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&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;[MySQL] 문자열 자르기 (SUBSTR, SUBSTRING)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요. 오늘은 MySQL에서 간단하게 문자열을 추출하거나 자를 때 사용하는 함수에 대해 알아보겠습니다. SQL 문자열 추출 함수 (SUBSTR, SUBSTRING) ▣ 문자열 자르기 함수 종류 RDBMS Function Oracle SUB&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingspooning.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jang8584.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jang8584.tistory.com/7&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687684984910&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;[mysql]날짜 관련 함수 모음&quot; data-og-description=&quot;[mysql-함수]날짜 관련 함수 모음 dayofweek(date) 날짜를 한 주의 몇 번째 요일인지를 나타내는 숫자로 리턴한다. (1 = 일요일, 2 = 월요일, ... 7 = 토요일) mysql&amp;gt; select dayofweek('1998-02-03'); -&amp;gt; 3 weekday(date) 날&quot; data-og-host=&quot;jang8584.tistory.com&quot; data-og-source-url=&quot;https://jang8584.tistory.com/7&quot; data-og-url=&quot;https://jang8584.tistory.com/7&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sRDXm/hyS6G1dBWs/I3EkLI3owvuzyo8acy5LwK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bl990Q/hyS6yWpOD4/iKWMo3nfkYZzNtKKnM6ERK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://jang8584.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jang8584.tistory.com/7&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sRDXm/hyS6G1dBWs/I3EkLI3owvuzyo8acy5LwK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bl990Q/hyS6yWpOD4/iKWMo3nfkYZzNtKKnM6ERK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&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;[mysql]날짜 관련 함수 모음&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[mysql-함수]날짜 관련 함수 모음 dayofweek(date) 날짜를 한 주의 몇 번째 요일인지를 나타내는 숫자로 리턴한다. (1 = 일요일, 2 = 월요일, ... 7 = 토요일) mysql&amp;gt; select dayofweek('1998-02-03'); -&amp;gt; 3 weekday(date) 날&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jang8584.tistory.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;</description>
      <category>DB : MySQL | Oracle | MyBatis</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/118</guid>
      <comments>https://maemae22.tistory.com/118#entry118comment</comments>
      <pubDate>Fri, 23 Jun 2023 15:48:47 +0900</pubDate>
    </item>
    <item>
      <title>[QueryDSL] org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list 에러</title>
      <link>https://maemae22.tistory.com/117</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 상황&lt;/h2&gt;
&lt;pre id=&quot;code_1684944126709&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Override
public ThemeDetailDTO themeDetail(Long themeId) {

    return queryFactory
            .select(new QThemeDetailDTO(
                    theme.id,
                    theme.name,
                    theme.genre,
                    theme.activity,
                    theme.difficult,
                    theme.limitTime,
                    theme.recommendStart,
                    theme.recommendEnd,
                    theme.info,
                    theme.imageUrl,
                    cafe.id,
                    cafe.name,
                    cafe.domain,
                    cafe.location,
                    Expressions.template(Double.class, &quot;ROUND({0}, 2)&quot;, review.rating.avg().coalesce(-1.0))
            ))
            .from(theme)
            .leftJoin(theme.cafe, cafe)
            .leftJoin(theme.reviews, review)
            .where(theme.id.eq(themeId))
            .fetchOne();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 위와 같이 코드를 작성하였는데, 문득 fetch join 이 추가되면 SQL문이 어떻게 출력될지 궁금해졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 .fetchJoin() 을 추가하여 아래와 같이 코드를 작성해봤다&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684944211079&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Override
public ThemeDetailDTO themeDetail(Long themeId) {

    return queryFactory
            .select(new QThemeDetailDTO(
                    theme.id,
                    theme.name,
                    theme.genre,
                    theme.activity,
                    theme.difficult,
                    theme.limitTime,
                    theme.recommendStart,
                    theme.recommendEnd,
                    theme.info,
                    theme.imageUrl,
                    cafe.id,
                    cafe.name,
                    cafe.domain,
                    cafe.location,
                    Expressions.template(Double.class, &quot;ROUND({0}, 2)&quot;, review.rating.avg().coalesce(-1.0))
            ))
            .from(theme)
            .leftJoin(theme.cafe, cafe).fetchJoin()
            .leftJoin(theme.reviews, review)
            .where(theme.id.eq(themeId))
            .fetchOne();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 실행하였더니 런타임 시 아래와 같은 오류가 발생하였다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3602&quot; data-origin-height=&quot;1102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QegCP/btshkax9owv/xebUU7vJkLGxgEVXY3hjuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QegCP/btshkax9owv/xebUU7vJkLGxgEVXY3hjuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QegCP/btshkax9owv/xebUU7vJkLGxgEVXY3hjuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQegCP%2Fbtshkax9owv%2FxebUU7vJkLGxgEVXY3hjuK%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;3602&quot; height=&quot;1102&quot; data-origin-width=&quot;3602&quot; data-origin-height=&quot;1102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;원인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fetch join을 사용하는 이유는 엔티티 상태에서 엔티티 그래프를 참조하기 위해서 사용하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 당연히 엔티티가 아닌 DTO 상태로 조회하는 것은 불가능하다.&lt;br /&gt;DTO로 조회할 경우 fetch join을 사용하면 안되며, 그냥 순수한 join을 사용해야 한다 .. !&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 즉, DTO 형식의 반환형에 fetchJoin()을 사용하면 안된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 DTO로 조회하는 경우에는 내가 처음에 했었던대로 순수한 join을 사용해서 데이터를 조회해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 DTO로 조회한 것이 아닌데 이 오류가 발생하였다면 아래 글을 참고해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/questions/240949/fetchjoin-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/questions/240949/fetchjoin-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684944653502&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;fetchJoin() 에러 발생 - 인프런 | 질문 &amp;amp; 답변&quot; data-og-description=&quot;안녕하세요fetchJoin() 할 때 에러가 발생하는데 해결방법을 찾을 수 없어 조언을 구합니다정상 동작query.from(A).leftjoin(A.B , B).fetchJoin()에러 발생query.from(A).leftjoin(A.B , B).fetchJoin().le...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/questions/240949/fetchjoin-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D&quot; data-og-url=&quot;https://www.inflearn.com/questions/240949/fetchjoin-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lFtC2/hySKECqKrg/zL7mWEYN8SbsxUJWkqgdV1/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_462,https://scrap.kakaocdn.net/dn/LNTfF/hySKxpLSrN/K1H6UgHA93s8GcKcipg1oK/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_462,https://scrap.kakaocdn.net/dn/jTOou/hySKE3ufSV/TW7PnYOLUeWVMeLQr9SGp0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/questions/240949/fetchjoin-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/questions/240949/fetchjoin-%EC%97%90%EB%9F%AC-%EB%B0%9C%EC%83%9D&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lFtC2/hySKECqKrg/zL7mWEYN8SbsxUJWkqgdV1/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_462,https://scrap.kakaocdn.net/dn/LNTfF/hySKxpLSrN/K1H6UgHA93s8GcKcipg1oK/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=751_416_794_462,https://scrap.kakaocdn.net/dn/jTOou/hySKE3ufSV/TW7PnYOLUeWVMeLQr9SGp0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;fetchJoin() 에러 발생 - 인프런 | 질문 &amp;amp; 답변&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요fetchJoin() 할 때 에러가 발생하는데 해결방법을 찾을 수 없어 조언을 구합니다정상 동작query.from(A).leftjoin(A.B , B).fetchJoin()에러 발생query.from(A).leftjoin(A.B , B).fetchJoin().le...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.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;</description>
      <category>escape-room</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/117</guid>
      <comments>https://maemae22.tistory.com/117#entry117comment</comments>
      <pubDate>Thu, 25 May 2023 01:11:11 +0900</pubDate>
    </item>
    <item>
      <title>[Java] java.time.format.DateTimeParseException: Text '2022-05-12' could not be parsed at index 10 에러 (String 날짜만 -&amp;gt; LocalDateTime 변환)</title>
      <link>https://maemae22.tistory.com/116</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 상황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리뷰 작성할 때 입력받은 플레이날짜(playdate) 를 받아오는 과정에서 해당 에러가 발생하였다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;java.time.format.DateTimeParseException: Text '2022-05-12' could not be parsed at index 10&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2154&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKVxSz/btshjdIIDNF/Iw094AUNjoWrLvzOxBI6h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKVxSz/btshjdIIDNF/Iw094AUNjoWrLvzOxBI6h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKVxSz/btshjdIIDNF/Iw094AUNjoWrLvzOxBI6h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKVxSz%2FbtshjdIIDNF%2FIw094AUNjoWrLvzOxBI6h1%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;2154&quot; height=&quot;582&quot; data-origin-width=&quot;2154&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;요청은 &lt;span style=&quot;background-color: #ffffff; color: #212121; text-align: left;&quot;&gt;2022-05-12 와 같이 'yyyy-MM-dd'의 날짜 형식으로 보낸다.&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212121; text-align: left;&quot;&gt;'2022-05-12' 을 LocalDateTime 으로 바꾸어보자&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 에러가 발생한 코드는 다음과 같다 : .playdate(LocalDateTime.parse(playdate))&lt;/p&gt;
&lt;pre id=&quot;code_1684928298444&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Data
public class ReviewDTO {

    private Long themeId;
    private String nickname;
    private String password;
    private String playdate;
    private Double difficult;
    private String clear;
    private String time;
    private Integer hint;
    private String content;
    private Double rating;

    public Review toEntity() {

        return Review.builder()
                .theme(Theme.builder().id(themeId).build())
                .nickname(nickname)
                .password(password)
                .playdate(LocalDateTime.parse(playdate))
                .difficult(difficult)
                .clear(clear)
                .time(time)
                .hint(hint)
                .content(content)
                .rating(rating)
                .build();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시도 1. DateTimeFormatter와 LocalDateTime.parse() 사용 - 실패&lt;/h2&gt;
&lt;pre id=&quot;code_1684929393249&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String dateString = &quot;2023-05-11&quot;;
        
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyy-MM-dd&quot;);
        LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
        
        System.out.println(dateTime);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 방법을 사용하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;pre id=&quot;code_1684929490936&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public Review toEntity() {

    return Review.builder()
            .theme(Theme.builder().id(themeId).build())
            .nickname(nickname)
            .password(password)
            .playdate(LocalDateTime.parse(playdate, DateTimeFormatter.ofPattern(&quot;yyyy-MM-dd&quot;)))
            .difficult(difficult)
            .clear(clear)
            .time(time)
            .hint(hint)
            .content(content)
            .rating(rating)
            .build();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 코드를 수정하고 실행해보니 아래와 같은 에러가 발생하였다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;java.time.format.DateTimeParseException: Text '2022-05-12' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2022-05-12 of type java.time.format.Parsed&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3574&quot; data-origin-height=&quot;1022&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhu1mk/btshhFGiLRy/6kdrt3fEsNZy3NbZtMJxs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhu1mk/btshhFGiLRy/6kdrt3fEsNZy3NbZtMJxs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhu1mk/btshhFGiLRy/6kdrt3fEsNZy3NbZtMJxs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdhu1mk%2FbtshhFGiLRy%2F6kdrt3fEsNZy3NbZtMJxs0%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;3574&quot; height=&quot;1022&quot; data-origin-width=&quot;3574&quot; data-origin-height=&quot;1022&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러가 발생하는 이유는 주어진 날짜 문자열 &quot;2023-05-11&quot;의 시간 부분이 누락되어 있기 때문이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LocalDateTime은 날짜와 시간을 함께 포함하므로, 입력된 문자열에 시간 정보가 없으면 파싱 과정에서 예외가 발생한다. &lt;br /&gt;&lt;br /&gt;따라서 문제를 해결하려면 입력된 날짜 문자열에 시간 정보를 추가해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 &quot;2023-05-11T00:00&quot;과 같이 시간을 설정한 형태로 문자열을 받아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684929711276&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String dateString = &quot;2023-05-11T00:00&quot;;

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(&quot;yyyy-MM-dd'T'HH:mm&quot;);
        LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);

        System.out.println(dateTime); // 출력: 2023-05-11T00:00
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 시간 정보가 포함된 문자열을 파싱할 경우 예외가 발생되지 않는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만 내가 원하는 건 'yyyy-MM-dd' 과 같은 날짜 형식 문자열을 LocalDateTime으로 바꾸는 것이었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 나는 다음 방법을 사용하여 문제를 해결하였다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시도 2. 'yyyy-MM-dd' 과 같은 날짜 형식 문자열을 LocalDate으로 파싱하고, LocalDate -&amp;gt; LocalDateTime으로 변경 (성공)&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1) 'yyyy-MM-dd'과 같은 날짜 형식 문자열을 LocalDate으로 파싱하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 playdate는 &quot;&lt;span style=&quot;background-color: #ffffff; color: #212121; text-align: left;&quot;&gt;2022-05-12&quot;과 같이 &quot;yyyy-MM-dd&quot; 형식의 날짜 문자열이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1684930323296&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LocalDate date = LocalDate.parse(playdate, DateTimeFormatter.ISO_DATE);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LocalDate.parse를 이용하면 문자를 파싱하여 LocalDate 객체를 생성할 수 있다.&lt;br /&gt;위 코드에서 DateTimeFormatter.ISO_DATE는 &quot;yyyy-MM-dd&quot;를 상수로 선언한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션을 사용하면 &quot;yyyy-MM-dd&quot; 형태의 스트링을 파싱할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2) LocalDate -&amp;gt; LocalDateTime으로 변경&lt;/h4&gt;
&lt;pre id=&quot;code_1684930667804&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;date.atStartOfDay()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.atStartOfDay() : 날짜 + 00:00:00을 의미&lt;br /&gt;.atTime(LocalTime.MAX) : 날짜 + 23:59:59.99999999를 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 2022-05-12 00:00:00 처럼 저장하기 위해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;date.atStartOfDay() 을 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684931164026&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.parse(&quot;2021-10-25&quot;, DateTimeFormatter.ISO_DATE);

        LocalDateTime localDateTime1 = date.atStartOfDay(); // 2021-10-25T00:00
        LocalDateTime localDateTime2 = date.atTime(LocalTime.MAX); // 2021-10-25T23:59:59.999999999

        System.out.println(&quot;localDateTime1 = &quot; + localDateTime1);
        System.out.println(&quot;localDateTime2 = &quot; + localDateTime2);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;최종 코드&lt;/h2&gt;
&lt;pre id=&quot;code_1684931458752&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Data
public class ReviewDTO {

    private Long themeId;
    private String nickname;
    private String password;
    private String playdate;
    private Double difficult;
    private String clear;
    private String time;
    private Integer hint;
    private String content;
    private Double rating;

    public Review toEntity() {
        LocalDate date = LocalDate.parse(playdate, DateTimeFormatter.ISO_DATE);

        return Review.builder()
                .theme(Theme.builder().id(themeId).build())
                .nickname(nickname)
                .password(password)
                .playdate(date.atStartOfDay())
                .difficult(difficult)
                .clear(clear)
                .time(time)
                .hint(hint)
                .content(content)
                .rating(rating)
                .build();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 작성하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리뷰 작성 API를 실행하니&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tHam2/btshgoLJMix/NXGluYSLj5qqW1EAVKCB31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tHam2/btshgoLJMix/NXGluYSLj5qqW1EAVKCB31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tHam2/btshgoLJMix/NXGluYSLj5qqW1EAVKCB31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtHam2%2FbtshgoLJMix%2FNXGluYSLj5qqW1EAVKCB31%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;247&quot; height=&quot;62&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공적으로 실행된 것을 확인할 수 있었다 !&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1878&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ExFv9/btshh8VVH4h/rw2OiPrQvz6F4oGj0YNuS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ExFv9/btshh8VVH4h/rw2OiPrQvz6F4oGj0YNuS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ExFv9/btshh8VVH4h/rw2OiPrQvz6F4oGj0YNuS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FExFv9%2Fbtshh8VVH4h%2Frw2OiPrQvz6F4oGj0YNuS0%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;679&quot; height=&quot;322&quot; data-origin-width=&quot;1878&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB에도 위와 같이 잘 저장되어 있다 !&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>escape-room</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/116</guid>
      <comments>https://maemae22.tistory.com/116#entry116comment</comments>
      <pubDate>Wed, 24 May 2023 21:33:24 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Page 객체 내의 필드값 변경하기</title>
      <link>https://maemae22.tistory.com/115</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제 상황&lt;/h2&gt;
&lt;pre id=&quot;code_1684860923345&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
@RequiredArgsConstructor
public class ThemeService {

    private final ThemeRepository themeRepository;

    public Page&amp;lt;ThemeListDTO&amp;gt; themeAllList(Pageable pageable) {
        return themeRepository.themeAllListPage(pageable);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Service단에서는 Repository단에서 받은 Page&amp;lt;ThemeListDTO&amp;gt; 를 그대로 넘겨주고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684861061155&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Getter
public class ThemeListDTO {

    private Long themeId;
    private String themeName;
    private String genre;
    private Integer recommendStart;
    private Integer recommendEnd;
    private String imageUrl;

    private String cafeName;
    private String location;

    private Double ratingAvg;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HByof/btsg7HEvz0P/ju8fu8VlGHXZDhNEMWWpG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HByof/btsg7HEvz0P/ju8fu8VlGHXZDhNEMWWpG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HByof/btsg7HEvz0P/ju8fu8VlGHXZDhNEMWWpG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHByof%2Fbtsg7HEvz0P%2Fju8fu8VlGHXZDhNEMWWpG0%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;566&quot; height=&quot;356&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 사실 DB에는 이미지 url 이 아닌 이미지 이름만 저장되어 있다 .. (위 사진 참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하게도 Repository에서 받아온 Page 객체의 ThemeListDTO에는 DB에서 받아온 값이 저장되어 있으므로 이미지 이름만 있는 상황이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이를 진짜 이미지 url으로 변경해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Page 객체 내의 필드값을 변경해보자 !&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Page 객체 내의 필드값을 바꾸는 방법&lt;/h2&gt;
&lt;pre id=&quot;code_1684862342458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;

// ...

// 기존의 Page&amp;lt;ThemeListDTO&amp;gt; 객체
Page&amp;lt;ThemeListDTO&amp;gt; page = themeRepository.themeAllListPage(pageable);

// 페이지의 내용을 가져옴
List&amp;lt;ThemeListDTO&amp;gt; content = page.getContent();

// 각 DTO의 필드 값을 변경
for (ThemeListDTO dto : content) {
    // 필드 값 변경 예시: name 필드를 &quot;New Name&quot;으로 변경
    dto.setName(&quot;New Name&quot;);
}

// 변경된 List&amp;lt;ThemeListDTO&amp;gt;를 사용하여 새로운 Page 객체 생성
Page&amp;lt;ThemeListDTO&amp;gt; updatedPage = new PageImpl&amp;lt;&amp;gt;(content, pageable, page.getTotalElements());

// 변경된 Page 객체 사용
// ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Page&amp;lt;ThemeListDTO&amp;gt;에서 DTO의 필드 값을 변경하고 싶다면, 위와 같이 코드를 작성하면 된다.&lt;br /&gt;&lt;br /&gt;1. Page&amp;lt;ThemeListDTO&amp;gt; 객체를 받는다. &lt;br /&gt;2. getContent() 메서드를 사용하여 페이지의 내용을 가져온다. 이는 List&amp;lt;ThemeListDTO&amp;gt;를 반환함. &lt;br /&gt;3. 각 ThemeListDTO 객체에 접근하여 필드 값을 변경한다. &lt;br /&gt;4. 변경한 List&amp;lt;ThemeListDTO&amp;gt;를 사용하여 새로운 Page 객체를 생성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예시)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전&lt;/h3&gt;
&lt;pre id=&quot;code_1684862468614&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public Page&amp;lt;ThemeListDTO&amp;gt; themeAllList(Pageable pageable) {
    return themeRepository.themeAllListPage(pageable);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;후&lt;/h3&gt;
&lt;pre id=&quot;code_1684863013032&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void changeImageUrl(String imageUrl) {
    this.imageUrl = imageUrl;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ThemeListDTO에 imageUrl을 바꾸는 메서드 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;: changeImageUrl 메서드를 통해 imageUrl을 바꿀 수 있음 (setter와 동일)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684863032158&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public Page&amp;lt;ThemeListDTO&amp;gt; themeAllList(Pageable pageable) {

    Page&amp;lt;ThemeListDTO&amp;gt; page = themeRepository.themeAllListPage(pageable);

    List&amp;lt;ThemeListDTO&amp;gt; content = page.getContent();

    for (ThemeListDTO dto : content) {
        String S3imgUrl = s3UploadService.getThumbnailPath(&quot;theme_img/&quot;+dto.getImageUrl());
        dto.changeImageUrl(S3imgUrl);
    }

    return new PageImpl&amp;lt;&amp;gt;(content, pageable, page.getTotalElements());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지&amp;nbsp;이름으로&amp;nbsp;S3에서&amp;nbsp;img&amp;nbsp;url을&amp;nbsp;찾아&amp;nbsp;반환하도록&amp;nbsp;변경 &lt;br /&gt;&amp;nbsp;: Repository에서 받은 Page에서 .getContent() 으로 List을 꺼내 imageUrl을 S3에서 받아온 image url로 변경 후, 변경된 내용으로 새로운 Page 객체를 생성해 반환함&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전체 코드 (Github)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/maemae22/escape-room/pull/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/maemae22/escape-room/pull/37&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684863200972&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;refactor: #21 - [GET] 테마 전체 목록 조회 API 변경 (소수점 반올림, 이미지 url S3에서 받아오도록 Page &quot; data-og-description=&quot;refactor: #21 - 리뷰 평점 반올림하여 소수점 둘째 자리로 출력되도록 변경 Expressions.template() 메서드를 사용하여 ROUND(@@, 2) 함수를 적용함 정리 : https://maemae22.tistory.com/114 feat: #21 - ThemeListDTO에 imageUrl&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/maemae22/escape-room/pull/37&quot; data-og-url=&quot;https://github.com/maemae22/escape-room/pull/37&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/01One/hySJgvNDZi/2TuLrYD9mo25FI3hIKq7E0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/maemae22/escape-room/pull/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/maemae22/escape-room/pull/37&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/01One/hySJgvNDZi/2TuLrYD9mo25FI3hIKq7E0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;refactor: #21 - [GET] 테마 전체 목록 조회 API 변경 (소수점 반올림, 이미지 url S3에서 받아오도록 Page&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;refactor: #21 - 리뷰 평점 반올림하여 소수점 둘째 자리로 출력되도록 변경 Expressions.template() 메서드를 사용하여 ROUND(@@, 2) 함수를 적용함 정리 : https://maemae22.tistory.com/114 feat: #21 - ThemeListDTO에 imageUrl&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첨언하자면 예시와 같이 S3에서 받아온 url을 그대로 사용하는 것은 좋지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS S3 &lt;span style=&quot;color: #212121; text-align: left;&quot;&gt;S3의 엔드포인트 주소를 그대로 사용해야 한다는 점, &lt;/span&gt;버킷이 퍼블릭 공개라는 점, 캐싱을 사용하지 못한다는 점, 서버 부담 및 비용 상의 문제 등의 이유로 CloudFront와 같은 CDN을 통해 &lt;span style=&quot;color: #212121; text-align: left;&quot;&gt;S3는 Cloudfront 뒤에 숨기고 Cloudfront를 통해서만 접근이 가능하도록 설정하는 것이 좋다.. !&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #212121; text-align: left;&quot;&gt;(참고)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/6217/&quot;&gt;https://techblog.woowahan.com/6217/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684863632417&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;사례별로 알아본 안전한 S3 사용 가이드 | 우아한형제들 기술블로그&quot; data-og-description=&quot;우아한형제들 인프라보안팀에서 근무하고 있는 이주호입니다. &amp;lsquo;S3를 왜 안전하게 사용해야 하는지 이해&amp;rsquo;하고 몇 가지 사례를 예시로 들어 &amp;lsquo;더욱 안전하게 사용하기 위해 설정해야 하는 기능&quot; data-og-host=&quot;techblog.woowahan.com&quot; data-og-source-url=&quot;https://techblog.woowahan.com/6217/&quot; data-og-url=&quot;https://techblog.woowahan.com/6217/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/NMstU/hySJdTni15/ryLmAj5KcUOryKzcY5SGMk/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/biOovU/hySJoUXFYI/6ozONjLaPIxjqOAMC74OZk/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/6217/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://techblog.woowahan.com/6217/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/NMstU/hySJdTni15/ryLmAj5KcUOryKzcY5SGMk/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/biOovU/hySJoUXFYI/6ozONjLaPIxjqOAMC74OZk/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856');&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;사례별로 알아본 안전한 S3 사용 가이드 | 우아한형제들 기술블로그&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;우아한형제들 인프라보안팀에서 근무하고 있는 이주호입니다. &amp;lsquo;S3를 왜 안전하게 사용해야 하는지 이해&amp;rsquo;하고 몇 가지 사례를 예시로 들어 &amp;lsquo;더욱 안전하게 사용하기 위해 설정해야 하는 기능&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;techblog.woowahan.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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #212121; text-align: left;&quot;&gt;본문의 예제는 Page 객체 내의 필드값을 변경하는 예제로만 참고하자 .. !&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>escape-room</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/115</guid>
      <comments>https://maemae22.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 24 May 2023 02:35:53 +0900</pubDate>
    </item>
    <item>
      <title>[QueryDSL] 소수점 반올림하기, ROUND 함수 사용하기 (ex.소수점 n번째 자리까지 반올림하기)</title>
      <link>https://maemae22.tistory.com/114</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;테마 리스트에서 리뷰 평점을 출력하는데&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKmwpr/btsg9PBkcfD/MKzb0l8WAe3LlfI0VRVJLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKmwpr/btsg9PBkcfD/MKzb0l8WAe3LlfI0VRVJLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKmwpr/btsg9PBkcfD/MKzb0l8WAe3LlfI0VRVJLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKmwpr%2Fbtsg9PBkcfD%2FMKzb0l8WAe3LlfI0VRVJLk%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;426&quot; height=&quot;254&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL문이 그냥 ~ avg(reviews.rating) ~ 으로 나가기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저렇게 표시되는 것을 볼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소수점 둘째짜리까지 나오도록 반올림해서 출력해보자 !&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 상태는 select 절 안에 아래와 같이 입력되어 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1684846421156&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;review.rating.avg().coalesce(-1.0)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시도 1. round() 함수 - 실패&lt;/h2&gt;
&lt;pre id=&quot;code_1684845825814&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;review.rating.avg().coalesce(-1.0).round()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btjGs6/btsg9v4frBU/XXhR6KlSNkhn2sbT66pX50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btjGs6/btsg9v4frBU/XXhR6KlSNkhn2sbT66pX50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btjGs6/btsg9v4frBU/XXhR6KlSNkhn2sbT66pX50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtjGs6%2Fbtsg9v4frBU%2FXXhR6KlSNkhn2sbT66pX50%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;375&quot; height=&quot;246&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 소수점 첫째자리에서 반올림된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;round(2) 와 같이 파라미터를 넣어보려고 했지만 불가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQL문도 round(coalesce(avg(reviews2_.rating), -1.0)) 으로 출력되는 것을 확인 ..&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시도 2. Expressions.template() 메서드 사용 (데이터베이스 방언에 따라 패턴 설정) - 성공&lt;/h2&gt;
&lt;pre id=&quot;code_1684846395023&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Expressions.template(Double.class, &quot;ROUND({0}, 2)&quot;, review.rating.avg().coalesce(-1.0))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;578&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beEGSJ/btshar1iNKw/ke637WwxDNRzLfLRWukHOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beEGSJ/btshar1iNKw/ke637WwxDNRzLfLRWukHOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beEGSJ/btshar1iNKw/ke637WwxDNRzLfLRWukHOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeEGSJ%2Fbtshar1iNKw%2Fke637WwxDNRzLfLRWukHOK%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;350&quot; height=&quot;271&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;578&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공 .. !&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Expressions.template() 메서드를 사용하여 MySQL의 ROUND() 함수를 쿼리에 적용하였다. &lt;u&gt;(본인이 설정해놓은 데이터베이스 방언에 따라 조금 다를 수 있음)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리에 ROUND 함수를 적용하였고, {0} 자리에 review.rating.avg().coalesce(-1.0)을 삽입한다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 ROUND({0}, 2) 라고 했기 때문에 소수점 둘째 자리까지 반올림되어 표시되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 n번째 자리에서 반올림하고 싶다면 ROUND({0}, 2) 에서 2 부분을 원하는대로 바꾸면 된다. (MySQL의 ROUND 함수 사용법 참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p6spy 로그를 보니 select 절에 내가 의도한 대로 아래와 같이 쿼리가 나간 것을 확인할 수 있었다 ! ㅎㅎ&lt;/p&gt;
&lt;pre id=&quot;code_1684846654161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;round(coalesce(avg(reviews2_.rating), -1.0), 2)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 위의 코드가 길어서 불편하다면&lt;/p&gt;
&lt;pre id=&quot;code_1684846494735&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;NumberExpression&amp;lt;Double&amp;gt; avgRating = review.rating.avg().coalesce(-1.0));
NumberExpression&amp;lt;Double&amp;gt; roundedAvgRating = Expressions.template(Double.class, &quot;ROUND({0}, 2)&quot;, avgRating);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 메서드를 추출해도 된다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1684847086819&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;

NumberExpression&amp;lt;Double&amp;gt; avgRating = review.rating.avg();
NumberExpression&amp;lt;Double&amp;gt; roundedAvgRating = Expressions.template(Double.class, &quot;ROUND({0}, 2)&quot;, avgRating);

queryFactory
    .select(new QThemeListDTO(
            theme.id,
            theme.name,
            roundedAvgRating))
    .from(theme)
    .leftJoin(theme.cafe, cafe)
    .leftJoin(theme, review.theme)
    .orderBy(roundedAvgRating.desc())
    .offset(pageable.getOffset())
    .limit(pageable.getPageSize())
    .fetch();&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;전체 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684902448792&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;refactor: #21 - 리뷰 평점 반올림하여 소수점 둘째 자리로 출력되도록 변경 &amp;middot; maemae22/escape-room@5648c69&quot; data-og-description=&quot;- Expressions.template() 메서드를 사용하여 ROUND(@@, 2) 함수를 적용함 - 정리 : https://maemae22.tistory.com/114&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2&quot; data-og-url=&quot;https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvCWNX/hySJfqlrY8/jRZtxFvYaJSYRVCjOT9Rvk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/maemae22/escape-room/commit/5648c699f5334bc323334f0f9199b3976d1a32c2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvCWNX/hySJfqlrY8/jRZtxFvYaJSYRVCjOT9Rvk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;refactor: #21 - 리뷰 평점 반올림하여 소수점 둘째 자리로 출력되도록 변경 &amp;middot; maemae22/escape-room@5648c69&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- Expressions.template() 메서드를 사용하여 ROUND(@@, 2) 함수를 적용함 - 정리 : https://maemae22.tistory.com/114&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.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;</description>
      <category>escape-room</category>
      <author>기매_</author>
      <guid isPermaLink="true">https://maemae22.tistory.com/114</guid>
      <comments>https://maemae22.tistory.com/114#entry114comment</comments>
      <pubDate>Tue, 23 May 2023 22:05:39 +0900</pubDate>
    </item>
  </channel>
</rss>