<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>valor_lee.log</title>
        <link>https://velog.io/</link>
        <description>안녕하세요. 엉덩이 7톤, 365일 성실한 백엔드 개발자, 이원일입니다.</description>
        <lastBuildDate>Wed, 14 Jun 2023 09:41:18 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>valor_lee.log</title>
            <url>https://velog.velcdn.com/images/valor_lee/profile/667e4a1e-0556-4df1-a2e6-0a53f81479fd/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. valor_lee.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/valor_lee" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[programmers SQL group by 년, 월, 성별 별 상품 구매 회원 수 구하기]]></title>
            <link>https://velog.io/@valor_lee/programmers-SQL-group-by-%EB%85%84-%EC%9B%94-%EC%84%B1%EB%B3%84-%EB%B3%84-%EC%83%81%ED%92%88-%EA%B5%AC%EB%A7%A4-%ED%9A%8C%EC%9B%90-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@valor_lee/programmers-SQL-group-by-%EB%85%84-%EC%9B%94-%EC%84%B1%EB%B3%84-%EB%B3%84-%EC%83%81%ED%92%88-%EA%B5%AC%EB%A7%A4-%ED%9A%8C%EC%9B%90-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 14 Jun 2023 09:41:18 GMT</pubDate>
            <description><![CDATA[<p>처리할 일을 끝내고 공부했던 내용 중에 공유하고 싶은 내용이 있어서 글을 남겨봅니다.
많은 의견이나 피드백 공유했으면 좋겠습니다.</p>
<p>저는 데이터베이스에 관심이 많다보니 SQL 문제를 풀면서 쿼리 작성 연습하고 있습니다.
오늘 프로그래머스 SQL group by 문제 중 <code>년,월, 성별 별 상품 구매 회원 수 구하기 문제</code>를 풀었습니다.</p>
<h3 id="문제">문제</h3>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/131532">programmers SQL group by 년, 월, 성별 별 상품 구매 회원 수 구하기</a></p>
<ul>
<li>USER_INFO 테이블과 ONLINE_SALE 테이블에서 년, 월, 성별 별로 상품을 구매한 회원수를 집계하는 SQL문을 작성해주세요. 결과는 년, 월, 성별을 기준으로 오름차순 정렬해주세요. 이때, 성별 정보가 없는 경우 결과에서 제외해주세요.</li>
<li>동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.</li>
</ul>
<h3 id="풀이">풀이</h3>
<p>이 문제의 핵심은 <mark>group by에 의해 발생하는 중복 데이터를 어떻게 처리할 것인가</mark>가 핵심이라고 생각합니다.</p>
<p>처음 완전한 쿼리를 고안해서 작성했더니 오답 행진이었습니다.
이후 데이터 조회 조건을 하나씩 추가하면서 제 쿼리의 허점을 찾으려고 노력했습니다.</p>
<pre><code class="language-sql">SELECT 
    *,
    COUNT(USER_ID) AS USERS
FROM 
    ONLINE_SALE
GROUP BY YEAR(SALES_DATE), MONTH(SALES_DATE)
;</code></pre>
<p>처럼 데이터 값을 조회하는 과정에서 문제의 조건은 년,월 별인데, 일일별로 유저가 반복 주문했을 경우 중복이 발생한다는 것을 알 수 있었습니다.</p>
<p>이를 해결하기 위해서 모든 조회 조건을 추가한 뒤, <mark>USER_ID에 DISTINCT 조건을 추가</mark>했습니다.</p>
<pre><code class="language-sql">SELECT 
    YEAR(OS.SALES_DATE) AS YEAR,
    MONTH(OS.SALES_DATE) AS MONTH,
    SQ.GENDER, 
    COUNT(DISTINCT OS.USER_ID) AS USERS
FROM 
    ONLINE_SALE OS
INNER JOIN
    (        
        SELECT
            USER_ID,
            GENDER
        FROM
            USER_INFO
        WHERE
            GENDER IS NOT NULL
    ) SQ
ON OS.USER_ID = SQ.USER_ID
GROUP BY YEAR, MONTH, SQ.GENDER
ORDER BY YEAR, MONTH, SQ.GENDER
;</code></pre>
<p>이렇게 정답을 맞췄는데,, </p>
<h3 id="최적화">최적화</h3>
<p>저는 항상 제가 작성한 코드가 못마땅하더라구요. 그래서 어떤 부분을 고칠 수 있을까 고민을 자주합니다.
이번에는 chatGPT 선생님께 코드 개선에 대한 피드백을 요청했습니다.</p>
<blockquote>
<p>WHERE 조건문을 JOIN 조건으로 이동시켜 sub query를 없애라</p>
</blockquote>
<p>고 조언해주셨습니다.</p>
<pre><code class="language-sql">SELECT 
    YEAR(OS.SALES_DATE) AS YEAR,
    MONTH(OS.SALES_DATE) AS MONTH,
    UI.GENDER, 
    COUNT(DISTINCT OS.USER_ID) AS USERS
FROM 
    ONLINE_SALE OS
INNER JOIN
    USER_INFO UI
ON OS.USER_ID = UI.USER_ID AND UI.GENDER IS NOT NULL
GROUP BY YEAR, MONTH, UI.GENDER
ORDER BY YEAR, MONTH, UI.GENDER;
</code></pre>
<br>

<p>하지만, 저는 <code>distinct</code>를 사용한 게 아쉬웠었습니다. 해당 키워드는 중복된 데이터를 제거할 때 조회 결과를 검사하며 중복을 제거하기 때문에 비효율적이라고 알고 있기 때문입니다. 
하지만 개선 방법을 찾지 못하기도 했고, 직관적이고 최적화된 데이터베이스에서는 빠른 성능을 보인다고 하니, 여기서 코드 개선을 마쳤습니다.</p>
<p>혹시, 쿼리에 다른 의견이 있으시다면 의견을 나누고 싶습니다 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GIT] clone 시, Authentication failed]]></title>
            <link>https://velog.io/@valor_lee/GIT-clone-%EC%8B%9C-Authentication-failed</link>
            <guid>https://velog.io/@valor_lee/GIT-clone-%EC%8B%9C-Authentication-failed</guid>
            <pubDate>Thu, 01 Jun 2023 09:21:42 GMT</pubDate>
            <description><![CDATA[<p>mac에서 github의 원격 저장소 clone을 시도했는데,,,</p>
<h2 id="에러">에러</h2>
<pre><code>https://github.com/WonilLee211/repo.git
Cloning into &#39;repo&#39;...
Username for &#39;https://github.com&#39;: wonillee211
Password for &#39;https://wonillee211@github.com&#39;:
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for &#39;https://github.com/WonilLee211/privacy.git/&#39;</code></pre><p>비밀번호 인증 과정에서 에러를 만났습니다.</p>
<p>메세지를 읽어보니, 21년 8월 13일부로 비밀번호 인증방식 지원이 종료됐다네요.</p>
<h2 id="해결">해결</h2>
<p>이를 해결하기 위해서 1. token 인증과 2. ssh clone 방식이 있습니다.
둘 다 시도해본 결과,
토큰 인증 방식이 생성된 토큰을 잘 관리해뒀다가 비밀번호 대용으로 사용하기 때문에 훨씬 편리했습니다.</p>
<p>그래서 token 인증 방식을 소개해드리고자 합니다.</p>
<h3 id="1token-생성">1.token 생성</h3>
<ul>
<li><p>github 접속</p>
</li>
<li><p><code>setting</code> - side tap 최하단에 <code>developer settings</code> - <code>personal access tokens</code> - <code>tokens</code> - <code>generate new token</code>(저는 beta가 아닌 classic으로 진행했습니다.)
<img src="https://velog.velcdn.com/images/valor_lee/post/da921b76-edde-4df3-9ed6-4f78f19a4b60/image.png" alt=""></p>
</li>
<li><p>위에서 원하는 expiration period를 선택하시고 scope를 선택하면 됩니다.
  저는 로컬에서 작업할 거라 모든 scope를 선택했습니다.</p>
<blockquote>
<p>주의 : 여기서 생성된 토큰을 저장하고 있어야 합니다.</p>
</blockquote>
<h3 id="2-mac-keychain-삭제">2. mac keychain 삭제</h3>
</li>
<li><p>spotlight에서 <code>keychain access</code> 검색
<img src="https://velog.velcdn.com/images/valor_lee/post/cee20edb-9ffa-4966-8009-3e8618fd4fe9/image.png" alt=""></p>
</li>
<li><p>저기 keychain이 login이라고 되어 있는 github.com을 우클릭하여 삭제하면 됩니다.</p>
</li>
</ul>
<h3 id="3-로그인하기">3. 로그인하기</h3>
<ul>
<li>동일한 방식으로 git push를 진행하면 password 입력 시, 토큰을 입력하시면 됩니다.</li>
</ul>
<pre><code class="language-bash">$ Username for https://github.com : 
$ Password for https://github.com/WonliLee211 :</code></pre>
<br>



<p><em>피드백 환영합니다.</em></p>
<h3 id="감사합니다">감사합니다.</h3>
]]></description>
        </item>
    </channel>
</rss>