728x90
반응형

안녕하세요!
오늘은 프로그래머스 SQL 고득점 Kit 중 SELECT 분야의 ‘조건에 맞는 개발자 찾기’ 문제 리뷰를 진행하겠습니다.

문제는 아래 링크에서 확인해주시면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/276034

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제 설명

 

  • 문제

 

  • 예시

728x90

  • 문제를 파악하며 쿼리 생각하기

예시에서 볼 수 있듯이, 저희가 문제에서 SELECT 해야 하는 부분은

  1. 개발자 ID : ID
  2. 이메일 : EMAIL
  3. 이름 : FIRST_NAME
  4. 성 : LAST_NAME

총 4개인 것을 볼 수 있습니다.

다음으로 저희가 WHERE 조건으로 확인해야 하는 부분은

  1. C# 혹은 Python 스킬을 가진 개발자 : NAME IN (‘C#’, ‘Python’)
    → 이름이 아니고 각 스킬에 해당하는 CODE 값으로 진행해도 됩니다. (CODE IN (1024, 256))

총 1개인 것을 확인할 수 있습니다.

다음으로 두 개의 테이블을 JOIN 해야하는 부분은

  1. DEVELOPERS 테이블의 SKILL_CODE 이진수 값 안에 SKILLCODES 테이블의 CODE 값이 들어있는 경우 : JOIN SKILLCODES b ON a.SKILL_CODES&b.CODE=b.CODE
    → 여기서 a는 DEVELOPERS 테이블의 별칭입니다.
    → 문제 설명처럼 개발자의 스킬 코드는 각 스킬 코드의 합으로 이루어져 있기 때문에, 어떤 합으로 이루어졌는지 알기 위해서는 비트 연산 &를 진행해야 합니다.

    ※ & 연산자는 이진수로 변경했을 때, 각 자릿수를 비교하여 동일하면 1, 다르면 0을 반환하는 연산자 입니다.
    → 문제 설명의 예시를 보시면 400(110010000)은 256(100000000)+128(10000000)+16(10000) 이고, 이를 각각 400과 &연산자를 진행하면 다음과 같은 결과물을 얻을 수 있습니다.

    ① 400&256 = 110010000&100000000 = 100000000 = 256
    ② 400&128 = 110010000&10000000 = 10000000 = 128
    ③ 400&16 = 110010000&10000 = 10000 = 16

    즉, DEVELOPERS의 SKILL_CODE와 CODE의 & 연산의 값이 CODE로 나오는 값개발자가 가진 스킬이라고 볼 수 있습니다.

위와 같은 것을 확인할 수 있습니다.

마지막으로 저희가 문제에서 확인해야 하는 부분은

  1. 개발자 ID로 오름차순 : ORDER BY ID

총 1개인 것을 확인할 수 있습니다.

 

  • 쿼리 완성하기

이제 위에서 생각한 쿼리를 SQL 실행순서에 맞게 배치해주시면 됩니다.
그렇게 완성된 쿼리는 아래와 같습니다.

-- C#과 Python 모두를 가진 개발자는 두 번 출력이 되기 때문에 DISTINCT를 해주어 중복값을 제거해줍니다.
SELECT  DISTINCT
        ID,
        EMAIL,
        FIRST_NAME,
        LAST_NAME
FROM    DEVELOPERS a
JOIN    SKILLCODES b ON a.SKILL_CODE&b.CODE=b.CODE
WHERE   NAME IN ('C#', 'Python')
ORDER BY 1


궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요!

오늘은 프로그래머스 SQL 고득점 Kit 중 GROUP BY 분야의 '대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기' 문제 리뷰를 진행하겠습니다.

 

문제는 아래 링크에서 확인해주시면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/151139

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제 설명

 

  • 문제

 

  • 예시

728x90
  • 문제를 파악하며 쿼리 생각하기

예시에서 볼 수 있듯이, 저희가 문제에서 SELECT 해야하는 부분은 

  1. 월 : MONTH(START_TIME) AS MONTH
    → 문제에서 날짜의 기준을 대여 시작일로 하고 있기 때문에 START_TIME을 해줘야 합니다.
    → MONTH() 는 DATE 타입에서 월을 가지고 오는 명령어 입니다.
    → MONTH는 문제 조건에 맞게 별칭으로 지정한 것 입니다.
  2. 자동차 ID : CAR_ID
  3. 월별 대여 횟수 : COUNT(*) AS RECORDS
    → 대여 횟수를 구하기 위해서 COUNT 집계 함수를 사용합니다.
    → RECORDS는 문제 조건에 맞게 별칭으로 지정한 것 입니다.

총 3개인 것을 확인할 수 있습니다.

 

다음으로 저희가 WHERE 조건으로 확인해야 하는 부분은

  1. 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차
    → 조건이 복잡하기 때문에 서브 쿼리를 사용해야 합니다.
  2. 2022년 8월부터 2022년 10월 동안 : START_DATE BETWEEN '2022-08-01' AND '2022-10-31'

총 2개인 것을 확인할 수 있습니다.

 

이번 문제에서는 WHERE 절 조건이 복잡하기 때문에 서브 쿼리를 사용해야 합니다.

서브 쿼리에서 확인해야 하는 부분은

  1. 자동차 : WHERE CAR_ID IN (SELECT CAR_ID
    → WHERE 절에 서브 쿼리를 쓰실 때 주의해야 할 점은 SELECT 절에 반드시 비교하고자 하는 하나의 컬럼을 사용해야 하는 것입니다.
    → 문제에서는 특정 기간 동안 대여 횟수 5회 이상인 자동차라고 했기 때문에 WHERE 절에 CAR_ID가 와야 하고 이에 맞게 서브 쿼리 안에 SELECT 안에도 CAR_ID만 올 수 있습니다.
  2. 2022년 8월부터 2022년 10월 : WHERE START_DATE BETWEEN '2022-08-01' AND '2022-10-31'
  3. 대여 횟수 5회 이상 :GROUP BY CAR_ID HAVING COUNT(*) >= 5)
    → 대여 횟수를 구하기 위해서 COUNT 집계 함수를 사용합니다.
    → 집계 함수 사용한 결과를 조건으로 걸어야 하기 때문에 HAVING을 사용합니다.
    → 집계 함수의 결과물을 사용할 수 없을 때, HAVING에서 바로 집계 함수를 사용하는 것이 가능합니다.

위와 같은 것을 확인할 수 있습니다.

다음으로 저희가 GROUP BY 해야하는 부분은

  1. 월별 자동차 대여 횟수 : GROUP BY MONTH(START_DATE), CAR_ID
    → 월별 대여 횟수이기 때문에 반드시 MONTH(START_DATE)를 해주셔야 합니다.
  2. 특정 월의 총 대여 횟수가 0인 경우 제외 : HAVING RECORDS != 0
    → 집계 함수의 결과를 조건으로 걸어야 하기 때문에 HAVING을 사용합니다.

위와 같은 것을 확인할 수 있습니다.

 

마지막으로 저희가 문제에서 확인해야 하는 부분은

  1. 월 기준 오름차순, 자동차 ID 기준 내림차순 : ORDER MONTH, CAR_ID DESC

총 1개인 것을 확인할 수 있습니다.

 

쿼리 완성하기

이제 위에서 생각한 쿼리를 SQL 실행 순서에 맞게 배치해주시면 됩니다.

그렇게 완성된 쿼리는 아래와 같습니다.

SELECT  MONTH(START_DATE) AS MONTH,
        CAR_ID,
        COUNT(*) AS RECORDS
FROM    CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE   CAR_ID IN (
        SELECT  CAR_ID
        FROM    CAR_RENTAL_COMPANY_RENTAL_HISTORY
        WHERE   START_DATE BETWEEN '2022-08-01' AND '2022-10-31'
        GROUP BY 1
        HAVING COUNT(*) >= 5
        )
        AND START_DATE BETWEEN '2022-08-01' AND '2022-10-31'
GROUP BY 1,2
HAVING RECORDS != 0
ORDER BY 1, 2 DESC

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요!

오늘은 프로그래머스 SQL 고득점 Kit 중 SELECT 분야의 '서울에 위치한 식당 목록 출력하기' 문제 리뷰를 진행하겠습니다.

 

문제는 아래 링크에서 확인해주시면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/131118

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제 설명

 

  • 문제

 

  • 예시

728x90

  • 문제를 파악하며 쿼리 생각하기

예시에서 볼 수 있듯이, 저희가 문제에서 SELECT 해야하는 부분은 식당의

  1. 식당 ID : REST_ID
  2. 식당 이름 : REST_NAME
  3. 음식 종류 : FOOD_TYPE
  4. 즐겨찾기 수 : FAVORITES
  5. 주소 : ADDRESS
  6. 리뷰 평균 점수 : AVG(REVIEW_SCORE)

총 6개인 것을 확인할 수 있습니다.

 

다음으로 JOIN 해야하는 부분은

  1. REST_INFO 와 REST_REVIEW를 REST_ID를 기준으로 동시 만족 : JOIN REST_REVIEW b ON a.REST_ID=b.REST_ID
    → a는 REST_INFO 의 별칭입니다.
    REST_INFO와 REST_REVIEW을 둘 다 만족해야 하기 때문에 내부 조인을 사용해야 합니다.
    → 내부 조인이기 때문에 REST_REVIEW에 REST_INFO를 JOIN하셔도 괜찮습니다.

위와 같은 것을 확인할 수 있습니다.

 

다음으로 저희가 WHERE 조건으로 확인해야 하는 부분은

  1. 서울에 위치한 식당 : ADDRESS LIKE '서울%'
    → 서울에 위치한 식당의 주소는 '서울시 ~~' 혹은 '서울특별시 ~~' 로 시작하기 때문에 주소에서 서울로 시작하는 문자열을 모두 가지고 와줍니다. 

총 1개인 것을 확인할 수 있습니다.

 

마지막으로 저희가 문제에서 확인해야 하는 부분은

  1. 리뷰 평균 점수는 소수점 세 번째 자리애서 반올림 : ROUND(AVG(REVIEW_SCORE), 2)
    → ROUND(x, y)는 x를 소수점 y자리 까지 반올림해서 보여주는 함수입니다.
    → 참고로 올림은 CEILING, 내림은 FLOOR을 사용해주시면 됩니다.
  2. 평균 점수 기준 내림차순, 즐겨찾기 수 내림차순 : ORDER BY AVG(REVIEW_SCORE) DESC, FAVORITES DESC
    → ORDER BY는 SELECT에서 진행한 별칭을 사용해도 되기 때문에, AVG(REVIEW_SCORE) 대신 별칭을 사용하시면 좋습니다.
    → ORDER BY는 SELECT에 나온 것을 기준으로 순서를 정렬하기 때문에 SELECT에 있는 컬럼의 순서로 적으셔도 됩니다.

총 2개인 것을 확인할 수 있습니다.

  • 쿼리 완성하기

이제 위에서 생각한 쿼리를 SQL 실행 순서에 맞게 배치해주시면 됩니다.

그렇게 완성된 쿼리는 아래와 같습니다.

SELECT  a.REST_ID,
        REST_NAME,
        FOOD_TYPE,
        FAVORITES,
        ADDRESS,
        ROUND(AVG(REVIEW_SCORE), 2) AS SCORE
FROM    REST_INFO a
JOIN   REST_REVIEW b ON a.REST_ID=b.REST_ID
WHERE   ADDRESS LIKE '서울%'
GROUP BY 1, 2, 3, 4, 5
ORDER BY 6 DESC, 4 DESC

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요!

오늘은 프로그래머스 SQL 고득점 Kit 중 GROUP BY 분야의 '저자 별 카테고리 매출액 집계하기' 문제 리뷰를 진행하겠습니다.

 

문제는 아래 링크에서 확인해주시면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/144856

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제 설명

 

  • 문제

 

  • 예시

 

  • 문제를 파악하여 쿼리 생각하기

예시에서 볼 수 있듯이, 저희가 문제에서 SELECT 해야하는 부분은 책의

  1. 저자 ID : AUTHOR_ID
    → AUTHOR_ID가 소속되어 있는 BOOK / AUTHOR 두 개의 테이블 중에서 아무 테이블에서 가져오시면 됩니다.
  2. 저자 이름 : AUTHOR_NAME
  3. 장르 : CATEGORY
  4. 총 매출 : SUM(PRICE*SALES) TOTAL_SALES
    → 각 책에 대한 금액과 판매 권수만 나와있기 때문에 금액*판매 권수를 하면 각 책의 매출 금액을 알 수 있습니다.
    → 저자별, 카테고리 별 총 매출액을 알고 싶기 때문에 각 책의 매출 금액을 합쳐야 최종 매출액을 구할 수 있습니다.
    → TOTAL_SALES는 총 매출액의 컬럼을 별칭으로 지정한 것 입니다.

총 4개인 것을 확인할 수 있습니다.

728x90

다음으로 테이블을 JOIN 해야하는 부분은

  1. BOOK 테이블과 AUTHOR 테이블을 AUTHOR_ID 기준으로 동시 만족 : JOIN AUTHOR b ON a. AUTHOR_ID=b. AUTHOR_ID
    → 여기서 a는 BOOK 테이블의 별칭이라고 생각하시면 됩니다.
  2. BOOK 테이블과 BOOK_SALES 테이블을 BOOK_ID를 기준으로 동시 만족 : JOIN BOOK_SALSE c ON a.BOOK_ID=c.BOOK_ID

위와 같은 것을 확인할 수 있습니다.

 

다음으로 저희가 WHERE 조건으로 확인해야 하는 부분은

  1. 2022년 1월 기준 : SALES_DATE LIKE '2022-01%'
    → 날짜가 '연도-월-일'의 형태로 들어오고 있고, 연도와 월만 생각하면 되기 때문에 일에 어떤 값이 와도 상관없다는 뜻으로 %를 붙여주시면 됩니다.
    → 만약 1월을 기준으로 한다면 SALES_DATE LIKE '%01%' 조건이 됩니다.

총 1개 인 것을 확인할 수 있습니다.

 

다음으로 저희가 GROUP BY 해야하는 부부은

  1. 저자 별 카테고리 별 : AUTHOR_ID, AUTHOR_NAME, CATEGORY, 
    → AUTHOR_NAME 는 AUTHOR_ID에 귀속되어져 있기 때문에 함께 GROUP BY 해주셔도 되고, 안해주셔도 됩니다만, 집계 함수를 제외한 나머지 컬럼은 최대한 모두 그룹화해주시는 것이 좋습니다.
    → AUTHOR_ID가 아닌 AUTHOR_NAME으로 그룹화를 하게되면, 동명이인 즉 이름은 동일하지만 다른 사람이 동일한 사람으로 집계가 되지 때문에 반드시 AUTHOR_ID가 기준이 되어야 합니다.

위와 같은 것을 확인할 수 있습니다.

 

마지막으로 저희가 문제에서 확인해야 하는 부분은

  1. 저자 ID 오름차순, 카테고리 내림차순 정렬 : ORDER BY AUTHOR_ID, CATEGORY DESC

총 1개인 것을 확인할 수 있습니다.

 

  • 쿼리 완성하기

이제 위에서 생각한 쿼리를 SQL 실행순서에 맞게 배치해주시면 됩니다.

그렇게 완성된 쿼리는 아래와 같습니다.

SELECT  b.AUTHOR_ID,
        AUTHOR_NAME,
        CATEGORY,
        SUM(PRICE*SALES) AS TOTAL_SALES
FROM    BOOK a
JOIN    AUTHOR b ON b.AUTHOR_ID=a.AUTHOR_ID
JOIN    BOOK_SALES c ON a.BOOK_ID=c.BOOK_ID
WHERE   SALES_DATE LIKE '2022-01%'
-- 숫자에 직접 컬럼 이름을 넣어주셔도 됩니다.
-- 각 숫자는 컬럼의 순서를 의미합니다.
GROUP BY 1,2,3
ORDER BY 1, 3 DESC

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

 

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요!

최근에 크롬 드라이버를 설치하는 페이지가 변경되어 새롭게 포스팅을 하겠습니다!

 

이전 포스팅이 궁금하신 분들은 아래 포스팅을 참고해주시면 됩니다!

https://yhj9855.com/entry/%ED%81%AC%EB%A1%AC%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84ChromeDriver-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

 

크롬드라이버(ChromeDriver) 설치하기

안녕하세요! 요즘 너무 바빠서 자주 글을 올리지 못하고 있네요ㅠㅠ 오늘은 동적 크롤링에 꼭 필요한 크롬드라이버(ChromeDriver)를 설치하는 방법에 대해서 포스팅 하겠습니다. 크롬드라이버란?

yhj9855.com

 

  • 크롬드라이버란?

컴퓨터가 크롬 브라우저를 제어할 수 있도록 해주는 프로그램입니다.

 

  • 크롬드라이버의 사용처

크롬드라이버는 컴퓨터 코드 크롬 브라우저에서 특정 행동을 하고 싶을 때 사용합니다.

※ 특정 행동은 스크롤을 내리거나, 버튼을 누르는 등의 행동을 예시로 들 수 있습니다.

크롬 브라우저를 직접 제어할 수 있기 때문에 URL이 변경되지 않는데 내용은 변경이 되는 동적 페이지 크롤링에 필수로 사용됩니다.

 

  • 크롬드라이버 설치하기

크롬드라이버는 크롬 버전과 버전이 맞지 않으면 코드에서 오류가 발생하기 때문에 꼭 동일한 버전의 크롬드라이버를 설치하는 것이 중요합니다.

크롬드라이버를 사용하는 selenium 패키지가 업데이트 되면서 크롬드라이버를 새롭게 설치할 필요가 없다고들 하는데, 저는 자꾸 오류가 발생해서 번거롭지만 버전에 맞는 크롬드라이버를 매번 다시 설치해주고 있습니다ㅠㅠ

크롬드라이버를 설치하는 과정은 아래와 같습니다.

1. 크롬을 최신 버전으로 업데이트 해줍니다.

최신 버전의 크롬이 가장 오류가 나지 않기 때문에 크롬드라이버를 설치하기 전에 크롬을 꼭 최신 버전으로 업데이트 해주세요!

 

2. 크롬의 버전을 확인합니다.

'제어' → '도움말' → 'Chrome 정보' 에서 크롬 버전을 확인할 수 있습니다.

여기서 제어는 크롬 내 X(창닫기 버튼) 아래에 있는 세로로 된 ... 을 의미합니다.

 

3. https://chromedriver.chromium.org/downloads 홈페이지에 접속합니다.

 

다운로드  |  ChromeDriver  |  Chrome for Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 다운로드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 달리 명시되지 않는 한 이 페이지의 콘텐츠

developer.chrome.com

구글에서 크롬드라이버를 검색했을 때, 가장 상단에 보이는 홈페이지와 동일한 홈페이지입니다!

 

4. 아래 이미지에 해당하는 부분을 클릭해줍니다.

메인 페이지가 변경되면서 다운로드 파일이 있는 곳으로 가는 버튼이 달라졌습니다!

현재 사용하시는 크롬은 무조건 115버전 보다 상위 버전이기 때문에 해당 부분을 클릭하여 최신 버전 다운로드 페이지로 이동해주세요!

 

5. 'Stable' 에서 자신에게 맞는 OS를 선택하여 다운로드를 받아줍니다.

다운로드는 URL을 복사하여 크롬 주소창에 입력해주면 자동으로 다운로드 진행이 됩니다.

자신에게 맞는 OS는 컴퓨터 내 '설정'  → '시스템'  → '시스템 종류'에서 확인 하실 수 있습니다!

728x90

※Stable에서 제공하는 크롬드라이버와 본인의 크롬 버전이 맞지 않을 경우

종종 크롬 업데이트가 잘 반영 되지 않아서, 현재 크롬 버전과 Stable에서 제공하는 크롬 버전이 다른 경우가 있습니다!

Stable에서 제공하는 크롬 버전은 아래 이미지처럼 확인이 가능합니다.

128.0.n.n 을 사용하시는 분들은 해당 버전이 맞지만, 127.n.n.n을 사용하시는 분들은 해당 버전이 맞지 않는데요!

이럴 경우에는 직접 검색을 하셔서 자신에게 맞는 크롬 드라이버 다운 링크를 찾으셔야 합니다.

 

1)  https://chromedriver.chromium.org/downloads 홈페이지에 다시 접속해주세요

뒤로 가기를 통해 메인 화면으로 돌아가셔도 됩니다!

 

2) 아래 이미지에 해당하는 부분을 클릭해줍니다.

 

3) 본인의 크롬 버전을 검색합니다.

검색은 Ctrl+F를 누르면 검색어를 입력할 수 있는 작은 창이 뜹니다.

해당 창에 자신의 크롬 버전을 검색해주시면 됩니다!

자신의 크롬 버전이 나타나지 않을 경우, 크롬 정보에서 가장 마지막 '.' 뒤를 제거하여 검색해주시면 됩니다!

예시) 크롬 버전: 127.0.6533.122 → 127.0.6533 을 검색

 

4) 본인의 크롬 버전과 동일하고 환경에 맞는 크롬 드라이버 다운로드 링크를 찾으시면 됩니다.

가장 마지막 '.' 뒤의 숫자는 달라도 같은 버전입니다!

예시) 127.0.6533.122의 크롬일 경우, 127.0.6533까지 동일한 파일이면 모두 호환 가능합니다.

다운로드 링크 찾는 방법

[1] chromedriver라는 값을 찾습니다.

 

[2] platform에서 자신에게 맞는 환경을 찾습니다.

저는 윈도우 64이기 때문에 해당 환경을 찾았습니다!

 

[3] url 값을 복사하여 주소창에 입력해줍니다.

자동으로 다운로드 되는 것을 확인하시면, 크롬 드라이버 다운로드가 잘 된 것입니다!

 

6. 설치 완료된 크롬드라이버 zip 파일에서 'chromedriver.exe' 파일만 복사하여, 코드가 있는 폴더에 옮겨줍니다.

같은 폴더에 있지 않으면, 코드가 인식하지 못하는 경우가 있어서 옮겨주는 것이 좋습니다.

 

이 과정을 통해서 최신 버전의 크롬드라이버를 설치할 수 있습니다!

크롬드라이버를 사용하여 동적 크롤링을 진행하는 포스팅은 다음에 진행하도록 하겠습니다.

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요! 요즘 몸이 별로 좋지 않아서 블로그 글을 거의 쓰지 못했네요ㅠㅠ

오늘은 빅쿼리(BigQuery)와 파이썬을 연동하는 방법에 대해서 포스팅 하겠습니다.

 

  • 빅쿼리(BigQuery) 란?

구글 클라우드 플랫폼에서 제공하는 클라우드 기반의 데이터웨어 하우스 서비스입니다.

구글 계정으로 관리하기 쉽기 때문에 요즘 다양한 회사에서 빅쿼리를 사용하고 있습니다.

 

  • 파이썬이랑 연동하는 이유
  1. 대용량 결과물 저장
    빅쿼리에서는 기본적으로 결과물을 csv 파일로 저장하거나, 스프레드 시트로 저장하는 기능을 제공하고 있습니다.
    하지만 데이터 결과물의 용량이 너무 클 경우에는 일부 데이터를 소실할 수 있는데, 데이터 분석의 특성 상 대용량의 데이터를 다루는 경우가 많기 때문에 생각보다 데이터가 소실되는 경우를 자주 경험할 수 있습니다.
    이런 경우 빅쿼리와 파이썬을 연동하여 로컬 PC에 바로 csv 혹은 xlsx 파일로 결과물을 저장할 수 있습니다!
  2. 쿼리로 해결하기 힘든 데이터  처리
    쿼리에서는 데이터의 직접적인 비교 등 진행하기 어려운 작업들이 있기 때문에 파이썬과 연동하여 데이터를 원하는 목적에 맞게 정제할 수 있습니다.
  3. 데이터 시각화
    데이터 분석은 쿼리를 통해 데이터를 집계하는 것 뿐만 아니라, 보고서 등을 위해서 데이터를 시각화 하는 작업이 빈번하게 발생합니다.
    요즘은 파이썬에서 데이터 시각화를 많이 진행하기 때문에 연동하여 진행하면, 시각화 작업을 수월하기 진행할 수 있습니다.

  • 필요한 라이브러리 설치하기

빅쿼리와 파이썬을 연결하기 위해서는 먼저 pandas-gbq 라는 라이브러리를 설치해야 합니다.

일반 라이브러리 설치하시는 것처럼 설치해주시면 됩니다!

pip install pandas-gbq

 

  • 코드 작성

파이썬 코드를 실행할 수 있는 실행기에서 아래 코드처럼 빅쿼리에서 실행이 가능한 쿼리와 함께 코드를 작성해주시면 손쉽게 빅쿼리 결과물을 로컬에 저장할 수 있습니다!

query="""
	빅쿼리에서 실행할 쿼리
"""

purchase_log = pd.read_gbq(query=query, dialect='standard', project_id='빅쿼리 프로젝트 이름', auth_local_webserver=True)
purchase_log.to_csv(f"저장하고자 하는 파일 경로", sep=",", index=False, encoding='cp949')

 

※주의 ※

데어터의 양이 많을 경우 코드가 실행되는 시간이 길기 때문에 반드시 쿼리를 먼저 빅쿼리에서 확인 후에 파이썬에서 실행해주세요!

한글 데이터가 포함되는 경우 encoding='cp949'를 포함하지 않으면, 한글이 깨질 수 있습니다.

데이터의 양이 많다면 파일의 경로는 D드라이브로 하는 것을 추천합니다!

 

 

  • 계정 선택

해당 코드를 처음 실행을 할 경우에는 크롬이 자동으로 뜨면서, 빅쿼리와 연결된 계정 선택 및 엑세스 요청 허가를 확인합니다.

알맞은 계정과 엑세스 허용을 하시면, 정상적으로 코드가 실행됩니다!

계정 선택의 과정은 컴퓨터마다 한 번만 진행이 됩니다.

 

실행이 완료되면, pandas를 이용해서 데이터를 정상적으로 로드할 수 있습니다.

1500만 정도 되는 데이터도 아주 잘 로드가 되는 것을 볼 수 있습니다!

 

빅쿼리는 파이썬과 연동하지 않으면 대용량 데이터를 저장하는 방법이 빅쿼리 자체에 테이블로 저장하는 방법 밖에 없기 때문에 파이썬에서 실행하는 방법을 익혀두시는 걸 추천드립니다!

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니★

728x90
반응형
728x90
반응형

안녕하세요!

오늘은 붕괴 스타레일 2.1 업데이트 모든 캐릭터 유물 및 차원 장식구 세팅 포스팅을 진행하겠습니다.

 

캐릭터의 유물, 차원 장신구 세팅은 엑셀 내 저장되어 있으며, 조회를 통해서 쉽게 보실 수 있습니다!

엑셀 파일을 조회하는 방법은 아래 포스팅을 참고해주세요:)

https://yhj9855.com/entry/%EB%B6%95%EA%B4%B4-%EC%8A%A4%ED%83%80%EB%A0%88%EC%9D%BC-%EC%9C%A0%EB%AC%BC-%EC%B0%A8%EC%9B%90-%EC%9E%A5%EC%8B%A0%EA%B5%AC-%EC%84%B8%ED%8C%85-%EC%97%91%EC%85%80-%ED%8C%8C%EC%9D%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

 

[붕괴 스타레일] 유물, 차원 장신구 세팅 엑셀 파일 사용하는 방법

안녕하세요. 오늘은 제가 만든 스타레일 유물, 차원 장신구 세팅이 담긴 엑셀 파일을 사용하는 방법에 대해서 포스팅 하겠습니다. 스타레일도 원신과 비슷하게 유물과 차원 장신구를 세팅해주

yhj9855.com

 

2.1 업데이트 기준으로 어벤츄린까지 캐릭터가 존재합니다.

유물 및 차원 장신구 세팅의 정보는 나무위키를 기반으로 하고 있습니다!

 

이번에 아케론과 어벤츄린 신규 캐릭터가 출시되었습니다!

아케론은 이전 캐릭터들과는 완전 다른 필살기를 가지고 있는데, 연출이 일단 너무 멋있어서 좋았습니다...

원신의 라이덴을 어느 정도 모티브 삼고 있기 때문에 확실히 비슷한 느낌이 들어서 좋은 느낌입니다!

아주 강력한 메인 딜러이기 때문에 파티가 조금 경직되는 감이 있어도 앞으로 자주 쓸 것 같네요.

 

아케론은 이번에 새로 나온 사수에 잠수한 선구자 4세트+이즈모 현세와 타카마 신국 2세트가 가장 베스트입니다.

사실상 사수에 잠수한 선구자는 아케론 쓰라고 나온 유물 느낌이 강해서 완전 찰떡인 친구입니다.

주옵션은 치명타 확률, 공격력 백분율 혹은 번개 속성 피해 증가로 맞춰주시면 됩니다.

 

 

어벤츄린은 일단 방어력 4000을 맞춰야 제대로 사용할 수 있기 때문에 방어력 4000을 맞추는데 힘들었네요ㅠㅠ

그래도 실드량이 진짜 어마무시해서 키워준 보람은 있는 캐릭터입니다. (게파드 안녕..)

 

어벤츄린은 정토 교황의 팔라딘 4세트+회전을 멈춘 살소토 2세트가 가장 베스트인 것 같아요!

아무래도 방어력 4000을 올려줘야 하기 때문에 거의 주옵션은 방어력 백분율로 맞추시면 됩니다.

 

자세한 유물 설명은 엑셀 파일에 있으니 사용해보시길 추천드립니다!

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

엑셀 파일은 아래 파일을 다운 받아주세요!

스타레일(2.1업데이트 기준).xlsx
0.09MB

 

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요!

오늘은 프로그래머스 SQL 고득점 Kit 중 JOIN 분야의 '있었는데요 없었습니다' 문제 리뷰를 진행하겠습니다.

 

문제는 아래 링크에서 확인해주시면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/59043

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제 설명

 

  • 문제

 

  • 예시

 

  • 문제를 파악하여 쿼리 생각하기

예시에서 볼 수 있듯이, 저희가 문제에서 SELECT 해야하는 부분은 동물의

  1. ID: A.ANIMAL_ID
  2. 이름: A.NAME
    → A는 ANIMAL_INS 테이블, B는 ANIMAL_OUTS 테이블을 의미합니다.
    → ID와 이름은 각 테이블에서 같이 포함되어 있기 때문에 어느 테이블에 존재하는지 꼭 명시를 해야합니다.
    → 여기서는 A, B 어느 테이블에 있는 값을 가지고 와도 동일한 값을 SELECT 합니다.

총 2개인 것을 확인할 수 있습니다.

 

다음으로 두 개의 테이블을 JOIN 해야하는 부분은

  1. ANIMAL_INS 테이블과 ANIMAL_OUTS 테이블을 동시에 만족: JOIN ANIMAL_OUTS B
    → 두 테이블을 동시에 만족해야 하기 때문에 내부 조인을 사용하는데, JOIN 혹은 INNER JOIN 으로 표기하시면 됩니다.
    → ANIMAL_OUTS을 FROM에 두고, ANIMAL_INS 테이블로 JOIN을 해도 상관 없습니다.
  2. 두 테이블에서 값이 동일한 컬럼이 기준: ON A.ANIMAL_ID=B.ANIMAL_ID
    → 두 테이블에서 동일한 값이 여러 개 있으나, 문제에서 ANIMAL_OUTS의 ANIMAL_ID는 ANIMAL_INS의 ANIMAL_ID의 외래 키라고 하였기 때문에 ANIMAL_ID로 JOIN하는 것이 좋습니다.
    → NAME, ANIMAL_TYPE 과 같은 값으로 JOIN을 할 경우, 테이블 내에 중복 값으로 인해 원하는 대로 JOIN이 되지 않을 가능성이 높습니다.

위와 같은 것을 확인할 수 있습니다.

 

다음으로 저희가 WHERE 조건으로 확인해야 하는 부분은

  1. 보호 시작일보다 입양일이 더 빠른 동물: A.DATETIME > B.DATETIME

총 1개인 것을 확인할 수 있습니다.

 

마지막으로 저희가 문제에서 확인해야 하는 부분은

  1. 결과는 보호 시작일이 빠른 순으로 조회: ORDER BY A.DATETIME

총 1개인 것을 확인할 수 있습니다.

 

 

  • 쿼리 완성하기

이제 위에서 생각한 쿼리를 SQL 실행순서에 맞게 배치해주시면 됩니다.

그렇게 완성된 쿼리는 아래와 같습니다.

SELECT 
    A.ANIMAL_ID, A.NAME
FROM 
    ANIMAL_INS A
JOIN 
    ANIMAL_OUTS B ON A.ANIMAL_ID = B.ANIMAL_ID
WHERE 
    A.DATETIME > B.DATETIME
ORDER BY 
    A.DATETIME

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요! 오늘은 원신 나무위키에 플레이어블 캐릭터성유물 카테고리의 글을 크롤링하는 코드에 대해 포스팅 진행하겠습니다.

해당 포스팅에서는 전체 코드와 결과물 이미지만 첨부합니다.

크롤링의 자세한 과정은 추후에 포스팅 진행하도록 하겠습니다.

 

해당 크롤링은 원신 각 캐릭터의 성유물 추천 옵션과 세트를 빠르게 파악하기 위한 데이터 수집을 목적으로 하고 있습니다!

나무위키에서 수집할 정보는 아래와 같습니다.

※ 사진 속 정보는 나히다를 예시로 한 것입니다.

1. 캐릭터의 이름, 속성, 무기

 

2. 권장 성유물 옵션

 

3. 추천 성유물 세트 및 설명

 

4. 성유물 이름, 세트 효과, 획득처

 

  • 크롤링 진행 방식

크롤링은 총 3개의 코드로 진행을 합니다.

 

  • 첫 번째 코드
  1. 원신 캐릭터의 상세 정보가 담긴 링크를 전부 긁어옵니다.
  2. 캐릭터의 이름과 링크만 저장하여 하나의 엑셀 파일로 저장합니다.
  • 두 번째 코드
  1. 첫 번째 코드에서 저장한 엑셀 파일에서 각 캐릭터의 상세 정보 링크를 가져옵니다.
  2. 캐릭터의 속성, 무기, 권장 성유물 옵션, 추천 성유물 세트 및 상세 설명의 내용을 가지고 옵니다.
  3. 캐릭터의 이름, 속성, 무기 권장 성유물 옵션을 저장하여 하나의 엑셀 파일로 저장합니다.
  4. 캐릭터의 이름, 추천 성유물 세트, 상세 설명을 저장하여 하나의 엑셀 파일로 저장합니다.

엑셀 파일을 두 개로 나눈 이유는 이후에 원신 캐릭터 성유물을 조회하는 엑셀 파일을 쉽게 만들기 위해서 입니다!

  • 세번째 코드
  1. 성유물 세트 이름, 2세트, 4세트, 획득처의 내용을 가지고 옵니다.
  2. 획득처에서 비경의 이름을 분리합니다.
  3. 성유물 세트 이름, 2세트, 4세트, 획득처, 비경의 이름을 저장하여 하나의 엑셀 파일로 저장합니다.

비경 이름을 분리한 이유는 이후 원신 캐릭터 성유물을 조회하는 엑셀 파일을 쉽게 만들기 위해서 입니다!

 

[실제 코드 및 결과물]

  • 첫 번째 코드
import pandas as pd
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as E
from openpyxl import *

# 원신/캐릭터 나무위키 링크
link = 'https://namu.wiki/w/%EC%9B%90%EC%8B%A0/%EC%BA%90%EB%A6%AD%ED%84%B0'

# 나무위키는 BeautifulSoup이 먹히지 않기 때문에 동적 크롤링으로 진행
driver = webdriver.Chrome('chromedriver.exe')
driver.get(link)
time.sleep(3)

# '원소별' 버튼 클릭
button = list(driver.find_elements(By.CLASS_NAME, "_3xTXXXtF"))
button[1].click()
time.sleep(3)

Character = pd.DataFrame({'캐릭터 이름' : [], '링크' : []})

character_info = driver.find_elements(By.CLASS_NAME, "s3zppxXT")

for i in range(len(character_info)) :
    character = character_info[i]
    # 캐릭터 이름만 담기 위해서 데이터를 정제하는 부분
    # 캐릭터의 소개가 끝나는 부분
    if character.text == '취소선' :
        break
    # 주인공 캐릭터인 아이테르와 루미네는 데이터 수집에서 제외
    # 캐릭터 이름이 아닌데, 들어온 정보는 모두 제외
    if character.text == '' or  '원신' in character.text or '아이테르' in character.text or character.text in ['불', '물', '바람', '번개', '풀', '얼음', '바위'] :
        pass
    else :
    	# 캐릭터의 이름
        name = character.text
        # 캐릭터의 이름이 길 경우, 엔터로 구분이 되어있기 때문에 이를 띄어쓰기로 변경
        if '\n' in name :
            name = name.replace('\n', ' ')
        Char = [name, str(character.get_attribute('href'))]
        Character.loc[i] = Char

with pd.ExcelWriter('genshin_link.xlsx') as writer :
    Character.to_excel(writer, sheet_name='링크', index=False)

 

  • 첫 번째 코드 결과물

 

  • 두 번째 코드
import pandas as pd
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as E
from openpyxl import *

# 캐릭터의 이름과 상세정보 링크가 담긴 엑셀 파일
link = pd.read_excel('genshin_link.xlsx')
Main_link = list(link['링크'])
Character = list(link['캐릭터 이름'])

Information = pd.DataFrame({'캐릭터 이름' : [], '무기' : [], '시간의 모래' : [], '공간의 성배' : [], '이성의 왕관' : [], '부옵션' : []})
Relic_Information = pd.DataFrame({'캐릭터 이름' : [], '성유물' : [], '평가': []})

driver = webdriver.Chrome('chromedriver.exe')

# 엑셀 전체 인덱스를 의미
# 저장할 엑셀이 두 개이기 때문에 인덱스도 두 개가 필요
total_index = 0
relic_index = 0

# 특정 캐릭터의 상세정보에서 오류가 발생할 경우을 대비
try :
    for k in range(len(Main_link)) :
        driver.get(Main_link[k])
        time.sleep(3)
        
        # 캐릭터의 무기 수집 과정
        attack = driver.find_elements(By.CLASS_NAME, 'cIflhYhI')
        for i in range(len(attack)) :
            if '무기' == attack[i].text :
                attack_index = i+1
                break
        weapon = attack[attack_index].text
        
        # 캐릭터의 성유물 수집 과정
        info = driver.find_elements(By.CLASS_NAME, 'D7SMSdcV')
        for i in range(len(info)) :
        	# 권장 성유물 옵션을 파악하기 위해 위치를 저장
            if '권장 성유물' in info[i].text :
                index = i
                break
        # 권성유물의 정보가 담긴 공간
        sung = info[index]
        
        # 권장 성유물 옵션 수집 과정
        options = sung.find_elements(By.CLASS_NAME, 'cIflhYhI')
        Option = [Character[k], weapon]
        for j in range(len(options)) :
        	# 권장 성유물 옵션에서 필요한 정보가 들어있는 부분
            if j in [4, 5, 6, 8] :
                option = options[j].text
                # 옵션이 여러 개일 경우, 줄바꿈으로 구분하기 때문에 이를 / 구분으로 변경
                if '\n' in option :
                    option = option.replace('\n', ' / ')
                Option.append(option)
        # 권장 성유물의 옵션만 담는 부분
        Information.loc[total_index] = Option
        total_index = total_index+1
        
        # 추천 성유물 세트 및 상세 설명 수집 과정
        sets = sung.find_elements(By.CLASS_NAME, 'W078FM6Z')
        # 성유물 세트는 캐릭터마다 여러 개 존재하기 때문에 이를 구분하기 위한 부분
        character_number = 1
        for j in range(len(sets)) :
            # li로 구분되어 있는데, 그 안에 div가 같이 들어가 있기 때문에 문제가 발생한다.
            relic_info = list(sets[j].text.split('\n'))
            for m in range(len(relic_info)) :
            	# 실제 정보가 들어가 있는 부분
                if m%2 == 1:
                    one_set = relic_info[m-1]
                    set_info =relic_info[m]
                    character_name = Character[k]+'%d' %(character_number)
                    Option = [character_name, one_set, set_info]
                    Relic_Information.loc[relic_index] = Option
                    character_number = character_number+1
                    relic_index = relic_index+1
except Exception as e :
    print(e)
    print(Main_link[k])
        
with pd.ExcelWriter('genshin.xlsx') as writer :
    Information.to_excel(writer, sheet_name='성유물 옵션', index=False)

with pd.ExcelWriter('genshin_set_relic.xlsx') as writer :
    Relic_Information.to_excel(writer, sheet_name='성유물', index=False)

 

  • 두 번째 코드 결과물

 

  • 세 번째 코드
import pandas as pd
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as E
from openpyxl import *

# 원신/성유물 나무위키 링크
link = 'https://namu.wiki/w/%EC%9B%90%EC%8B%A0/%EC%84%B1%EC%9C%A0%EB%AC%BC'

driver = webdriver.Chrome('chromedriver.exe')
driver.get(link)
time.sleep(3)

Relic = pd.DataFrame({'성유물 세트' : [], '2세트' : [], '4세트' : [], '획득처' : [], '비경' : []})
total_index = 0

# 성유물 세트 효과 수집 과정
info = driver.find_elements(By.CLASS_NAME, 'TiHaw-AK._6803dcde6a09ae387f9994555e73dfd7')
for i in range(len(info)) :
    # 첫 번째 성유물이 검투사의 피날레이기 때문에 해당 부분이 기준
    # 여기서부터 끝까지가 성유물에 대한 정보가 존재
    if '검투사' in info[i].text :
        index_start = i
        break
# 전체적으로 3단위로 원하는 정보가 있음
for i in range(index_start, len(info), 3) :
    relic_info = info[i].text.split('\n')
    # 1세트 효과가 있는 4성 성유물은 생략한다.
    if '모시는 자' in relic_info[0] :
        continue
    # 획득처에서 비경을 구분하는 과정
    if '비경' in  relic_info[7] :
        place_index_start = relic_info[7].index(':')
        place = relic_info[7][place_index_start+2:]
        if ',' in place :
            place_end_index = place.index(',')
            place = place[:place_end_index]
    else :
        place = ''
    relic = [relic_info[0], relic_info[3], relic_info[5], relic_info[7], place]
    Relic.loc[total_index] = relic
    total_index = total_index+1

with pd.ExcelWriter('genshin_relic.xlsx') as writer :
    Relic.to_excel(writer, sheet_name='성유물', index=False)

 

  • 세 번째 코드 결과물

 

해당 데이터를 활용하여 원신 캐릭터의 성유물을 엑셀에서 쉽게 조회하는 포스팅은 아래에서 확인해주세요!

https://yhj9855.com/entry/%EC%9B%90%EC%8B%A0-%EC%84%B1%EC%9C%A0%EB%AC%BC-%EC%84%B8%ED%8C%85-%EC%97%91%EC%85%80%EB%A1%9C-%EC%89%BD%EA%B2%8C-%EB%B3%B4%EA%B8%B0-45-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%EA%B8%B0%EC%A4%80-%EC%B9%98%EC%98%A4%EB%A6%AC-%ED%8F%AC%ED%95%A8

 

[원신] 성유물 세팅 엑셀로 쉽게 보기 (4.5 업데이트 기준, 치오리 포함)

안녕하세요! 오늘은 원신 4.5 업데이트 모든 캐릭터 성유물 세팅 포스팅을 진행하겠습니다. 4.5 업데이트는 간단한 업데이트여서 호다닥 갖고 왔습니다. 캐릭터의 성유물 세팅은 엑셀 내 저장되

yhj9855.com

 

코드에 대해 궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다!

★읽어주셔서 감사합니다★

728x90
반응형
728x90
반응형

안녕하세요!

오늘은 프로그래머스 SQL 고득점 Kit  중 GROUP BY 분야의 '조건에 맞는 사용자와 총 거래금액 조회하기' 문제 리뷰를 진행하겠습니다.

 

문제는 아래 링크에서 확인해주시면 됩니다.

https://school.programmers.co.kr/learn/courses/30/lessons/164668

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

  • 문제설명

  • 문제

  • 예시

 

  • 문제를 파악하여 쿼리 생각하기

예시에서 볼 수 있듯이, 저희가 문제에서 SELECT 해야하는 부분은 회원의

  1. ID: B.USER_ID
  2. 닉네임: B.NICKNAME
    → A는 USES_GOODS_BOARD 테이블, B는 USED_GOODS_USER 테이블을 뜻하는데, 컬럼 이름이 고유할 경우 소속 테이블을 명시해주지 않아도 SQL에서 구분이 가능합니다.
  3. 총 거래금액: SUM(A.PRICE) TOTAL_SALES
    → 거래금액만 존재하고, 총 거래금액은 존재하지 않기 때문에 총 거래금액은 거래금액을 합친 거라고 생각할 수 있습니다.
    → TOTAL_SALES는 총 거래금액의 컬럼을 별칭으로 지정한 것 입니다.

총 3개인 것을 확인할 수 있습니다.

 

다음으로 두 개의 테이블을 JOIN 해야하는 부분은

  1. USES_GOODS_BOARD 테이블과 USED_GOODS_USER 테이블을 동시에 만족: JOIN USED_GOODS_USER B
    → 두 테이블을 동시에 만족해야 하기 때문에 내부 조인을 사용하는데, JOIN 혹은 INNER JOIN 어떤 걸 사용하셔도 상관없습니다.
  2. 두 테이블에서 값이 동일한 컬럼이 기준: ON A.WRITER_ID = B.USER_ID
    → ON은 조인의 조건으로 두 테이블에서 값이 동일한 것은 회원 ID 밖에 없기 때문에 해당 부분으로 조인을 진행합니다.

위와 같은 것을 확인할 수 있습니다.

 

다음으로 저희가 WHERE 조건으로 확인해야 하는 부분은

  1. 완료된 중고 거래: A.STATUS = 'DONE'
    → 여기서 주의해야할 점은 총 금액이 70만원 이상인 조건은 총 금액의 조건이고, 테이블 자체에서는 총 금액이라는 컬럼이 없기 때문에 WHERE 조건에서는 사용할 수 없습니다.

총 1개인 것을 확인할 수 있습니다.

 

다음으로 저희가 GROUP BY 해야하는 부분은

  1. 총 거래금액을 제외한 나머지 부분: B.USER_ID, B.NICKNAME
    USER_ID 혹은 NICKNAME 각각으로 GROUP BY를 해도 두 개의 값이 모두 중복 값이 없기 때문에 동일한 결과물을 가지지만, 항상 그룹화하고 싶은 컬럼을 제외한 모든 컬럼으로 그룹화하는 것이 좋습니다.
  2. 총 금액이 70만원 이상: HAVING TOTAL_SALES >= 700000
    → HAVING은 GROUP BY의 조건으로 그룹화를 통해 생성된 컬럼에 조건을 걸 수 있습니다.

위와 같은 것을 확인할 수 있습니다.

 

마지막으로 저희가 문제에서 확인해야 하는 부분은

  1. 결과는 총 거래금액을 기준으로 오름차순 정렬: ORDER BY TOTAL_SALES

총 1개인 것을 확인할 수 있습니다.

 

쿼리 완성하기

이제 위에서 생각한 쿼리를 SQL 실행순서에 맞게 배치해주시면 됩니다.

그렇게 완성된 쿼리는 아래와 같습니다.

SELECT 
    B.USER_ID, 
    B.NICKNAME, 
    SUM(A.PRICE) TOTAL_SALES
FROM
    USED_GOODS_BOARD A
JOIN
    USED_GOODS_USER B ON A.WRITER_ID = B.USER_ID
WHERE
    A.STATUS = 'DONE'
GROUP BY 
    B.USER_ID, B.NICKNAME HAVING TOTAL_SALES >= 700000
ORDER BY 
    TOTAL_SALES

 

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

 

★읽어주셔서 감사합니다★

728x90
반응형

+ Recent posts