[내일배움캠프] 데이터 트랙/사전캠프

[내일배움캠프 사전캠프] 10일 차

554083460 2025. 5. 2. 17:51

 

 

SQL 퀘스트 마지막

 

 

문 44

모든 주문의 주문 ID와 주문된 상품의 이름을 나열하는 쿼리를 작성해주세요!

 

내 답안

SELECT o. id,
       p. name
FROM products p 
INNER JOIN orders o 
ON p.id=o.product_id;

 

예시 답안

SELECT o.id, p.name 
FROM orders o 
JOIN products p 
ON o.product_id = p.id;

 

- 헷갈린 점: JOIN을 사용할 때 주 테이블(parent table)을 먼저(왼쪽) 쓰는 것이 공식이라고 생각했다.

 

- 개선점 1:  코딩에서 규칙과 관례을 구분하는 것이 중요하다.

규칙 → 문법과 같다. 반드시 지켜야 한다. 규칙을 지키지 않으면 오류가 날 수 있다.
관례/ 관행  가독성, 소통, 원활한 협업을 위해 사용한다. 필수가 아닌 선택사항이다.

 

주 테이블(parent table, pk 가짐)을 왼쪽에 두는 것이 일반적이지만, 공식적인 규칙은 아니다.
문제의 의도나 쿼리의 흐름에 따라 자식 테이블(child table, fk 가짐)을 왼쪽에 둘 수도 있다.

 

- 개선점 2: 문제의 의도를 반영해서 코드 작성하는 게 좋다.

문제에서는 o.id와 p.name을 나열하라고 언급했다.

흐름상 o.id가 왼쪽에, p.name이 오른쪽에 위치하는 것이 자연스럽다.

따라서 JOIN구문에서 orders를 먼저(왼쪽) 써서 위와 같이 위치하게 한다.

 

 

문 45

총 매출(price * quantity의 합)이 가장 높은 상품의 ID와 해당 상품의 총 매출을 가져오는 쿼리를 작성해주세요!

 

내 답안

SELECT o.product_id,
       SUM(p.price*o.quantity) AS total_sales
FROM products p
INNER JOIN orders o
ON p.id=o.product_id
GROUP BY p.id
ORDER BY total_sales DESC
LIMIT 1;

 

예시 답안

SELECT p.id,
       SUM(p.price*o.quantity) AS total_sales
FROM products p
INNER JOIN orders o
ON p.id=o.product_id
GROUP BY p.id
ORDER BY total_sales DESC
LIMIT 1;

 

- 헷갈린 점 1: p.id와 o.product_id는 값이 같은 공통 column이다. 

SELECT와 GROUP BY에 p.id와 o.product_id를 하나씩 써도 결과가 같지 않을까?

 

- 개선점 1: SELECT와 GROUP BY에 같은 column을 쓰는 것이 일관성 있다. 

규칙은 아니지만 권장되는 관례다.

 

- 헷갈린 점 2: SELECT와 GROUP BY 모두에 p.id를 쓰는 것과
o.product_id를 쓰는 것이 다른가?

같은 값이니 결과가 같지 않을까?

 

- 개선점 2: 결과는 동일하지만 주 테이블(parent table)의 column을 쓰는 게 권장된다.

이것 역시 규칙은 아니지만 관례다.

 

1. 주 테이블과 자식 테이블 구분법

 

1) 주 테이블 (parent table)

- 고유 정보 저장

- 다른 테이블에서 이 정보를 참조한다.

 

2) 자식 테이블 (child table)
- 주 테이블의 primary key를 참조한다.

MySQL for Data Analytics and Business Intelligence by 365 Careers

 

 

문 48

가장 많이 판매된 상품의 이름을 찾는 쿼리를 작성해주세요!

 

내 답안

SELECT p.id,
       p.name,
       SUM(o.quantity) AS total_quantity
FROM products p 
INNER JOIN orders o 
ON p.id=o.product_id
GROUP BY p.id
ORDER BY total_quantity DESC
LIMIT 1;

 

예시 답안

SELECT p.name,
       SUM(o.quantity) AS total_quantity
FROM products p 
INNER JOIN orders o 
ON p.id=o.product_id
GROUP BY p.id
ORDER BY total_quantity DESC
LIMIT 1;

 

- 헷갈린 점: GROUP BY에 쓴 column을 SELECT에도 쓰는 것이 규칙이라고 생각했다.

 

- 개선점: 이것 역시 규칙이 아니라 관례다.

SELECT에도 쓰는 것이 좋은 경우 → 그룹화된 기준을 바탕으로 집계된 결과를 포함해야 할 때

SELECT에도 쓰는 것이 필요 없는 경우 → 이 문제처럼 가장 많이 판매된 이름을 출력하라고 하는 경우 하나의 행이 출력된다.

그룹화된 기준이 출력될 필요가 없으므로 SELECT에 p.id 넣을 필요 없다.

 

 


 

 

아티클 스터디: SQL 질문 잘 하는 방법

 

 

아티클

https://datarian.io/blog/how-to-ask-good-sql-questions

 

 


 

 

[주제]

 

SQL 질문 잘 하는 법

  1. 구글에서 검색하기
  2. 영문으로 검색하기
  3. 검색 키워드 잘 넣기
  4. 신뢰할 수 있는 사이트 클릭하기
  5. 언제 쓰여졌는지 확인하기

[아티클 요약]

 

코딩할 때 문제가 풀리지 않으면 다음과 같이 할 수 있다. 인터넷으로 검색하거나, 멘토에게 묻는 것이다. 질문 전에 스스로 아래의 5가지 사항을 확인하자.

  1. 코드 오탈자 확인
  2. 쿼리 실행 후 에러 메시지 뜨면, 그 메시지대로 조치 취한다.
  3. 문제에서 요구하는 조건을 다 충족했는가? 특히 WHERE절의 필터링 조건, ORDER BY 절의 정렬 조건, SELECT 절의 컬럼 이름이 정확한지 확인한다.
  4. 쿼리를 실행해본다. 질문하는 바 외에 다른 오류가 없는지도 확인한다.
  5. 여러 DBMS 선택할 수 있는 플랫폼에서 코드 작성 중이라면, 내가 쓰는 문법과 선택된 DBMS의 문법이 일치하는지 확인한다.

검색 잘하는 방법은 다음과 같다.

  1. 구글에서 검색한다. 기술 검색은 구글에서 하는 습관을 들이는 것이 좋다. 구글에 검색하면 공식 문서나 기술 커뮤니티(stackoverflow)의 페이지가 결과로 뜬다. 즉 양질의 정보를 얻을 수 있다.
  2. 영문으로 검색한다. 기술 검색 결과는 영어로 쓰인 문서가 많다. 영문 문서가 잘 노출되게 하려면 구글 언어 설정을 영어로 바꾸는 것이 좋다. 검색할 때는 필요한 단어를 단순 나열하면 된다.
  3. 검색 키워드를 잘 넣는다. 특정 DBMS의 특정 함수가 필요할 때는 ‘DBMS 이름 + 함수 이름’, 단순히 함수만 알고 싶을 때는 ‘SQL + 함수 이름’ 식으로 검색하면 된다.
  4. 신뢰할 수 있는 사이트에서 정보를 찾는다. 공식 문서를 가장 우선적으로 본다. MySQL 사이트는 http://dev.mysql.com/, PostgreSQL은 https://www.postgresql.org/ 이다.
  5. 글이 언제 쓰여졌는지 파악한다. SQL은 발전이 매우 빠르지는 않고, 표준이 정해져 있어 최신 문서만 봐야 할 필요는 없다. 하지만 특정 시점 이후 새롭게 추가된 함수가 있는 등 최신 정보를 봐야 하는 때도 있다.

[인사이트]

  • 코딩 공부를 할 때마다 느끼는 바가 있다. 검색을 잘 하는 게 중요하다는 것이다. 코딩은 오픈 북 테스트 같다. 함수나 메서드를 다 암기할 수 없으니 그때 그때 필요한 함수를 잘 검색하는 것이 필요한 것이다. 특히 SQL은 DBMS마다 문법이 조금씩 다르다. 이 사실을 잘 몰랐던 때는 SQL 문법을 검색할 때 ‘SQL 함수이름’을 입력했다. 이렇게 검색하니 현재 사용 중인 DBMS가 아닌 다른 DBMS 관련 문서가 상단에 있기도 했다. 글을 한참 읽다가 방금 읽은 내용이 다른 DBMS의 문법이었다는 걸 뒤늦게 깨닫고 허탈했던 적도 있다. 아티클 내용을 참고하여 이전보다 더 빠르게 검색할 수 있을 것 같다.