요약/나만의 인사이트
- SQL ⇒ 각 가격에 판매량을 곱해서 더한 값을 전체 판매량으로 나눈 것으로 가중평균이라고 한다. 가중평균은 AVG()함수를 쓸 수 없다. 왜냐하면 AVG()는 단순히 모든수를 더한값에 개수로 나눠주기 때문이다.
- 가중평균은 다음과 같다. SUM(가격 × 판매량) / SUM(판매량) 즉 각 상품별 판매량을 고려
- AVG는 다음과 같다. AVG(price) (100+200) /2
- 윈도우 함수는 행마다 도는 함수이다.
- rank over() row_number() 모두 순위를 구하는 윈도우 함수이다.
- rank over()은 공동순위면 같은 랭킹 번호 부여 1 2 2 4
- row_number()은 공동순위 일자라도 무조건 고유 랭킹 번호 부여한다. 1 2 3 4 이때 랭킹순서는 먼저 등장한 순서이다.
새롭게 알게 된 것
- 태블로
- 이중 축 사용시
- 축 이원화 : 두가지 모두 증감 추세 보고 싶을 때
- 축 동기화 : 두가지 비교해서 볼 때
- 행 수준 계산 vs 집계 수준 계산행 수준 계산 집계 수준 계산
개념 행 마다 계산 집계 된 후 계산 특징 세부데이터 기준으로 값이 계산됨 SUM, AVG, MIN, MAX 같은 집계 함수 사용 용도 행별 파생 변수 생성 전체 평균, 총합 대비 비율 계산 예시 매출 * 0.1 SUM([매출]) /SUM([전체매출]) - 매개변수
- 대시보드 상에서 사용자가 선택하면 그 값이 계산식, 필터, 참조선 등에 반영되어 뷰가 동적으로 변함!
- 따라서 별도로 계산식이나 필터와 연결해야 작동
- 매개변수 (차원) → 계산식 (측정값) 으로
- e.g.
- 참조선이라는 매개변수를 만듦. 값은 500으로 (분류기준)
- 그것과 관련된 SUM([C_측정값 선택])>=[P_참조선] C_참조선 색상 강조 측정값을 만들면 (계산식)
- 참조선(500)보다 큰 값과 작은 값이 다른 색상으로 표시 (연결)
- 이중 축 사용시
- SQL 복습
- CTE
Common Table Expression 으로 일시적으로 결과를 저장해서 메인 쿼리에서 다시 쓰기 위한 용도
복잡한 서브쿼리보다 가독성이 좋음.
WITH temp AS( SELECT … ) 형식임
하나의 SQL문 내에서 임시 결과 집합을 정의하고, 메인 쿼리에서 이를 재사용할 수 있게 해준다. - 상위 1%고객을 필터링 하기 위한 윈도우 함수
윈도우 함수
- CTE
-
-
- 행 단위로 연산을 하면서도, 다른 행들의 값을 함께 고려할 수 있게 해주는 함수
- 일반적인 GROUP BY와 달리, 집계를 하면서도 원래의 행을 유지할 수 있다.
RANK() 동일 값이 있으면 동일 순위, 다음 순위 건너뜀 1 2 2 4 ROW_NUMBER() 순위 1, 2, 3 …. 무조건 고유 순위 부여, 동일한 값이 나오면 나온순서대로 1 2 3 4 NTILE(n) 전체 데이터를 n개의 그룹으로 나눔 SUM() OVER() 윈도우 전체에서 누적합을 구함 ROW_NUMBER() 정렬 기준에 따라 행마다 고유 번호 부여 DENSE_RANK() 동일 값에 같은 순위 부여 (건너뛰지 않음) SUM(), AVG(), MAX(), MIN() 누적합, 이동 평균 등 가능 LAG(), LEAD() 이전 또는 다음 행의 값 가져오기 <윈도우 함수> OVER ( PARTITION BY <기준 컬럼> ORDER BY <정렬 기준> ROWS BETWEEN ... AND ... )- PARTITION BY: 그룹을 나눠서 계산 (선택사항)
- ORDER BY: 정렬 기준 (예: 시간 순으로 정렬)
- ROWS BETWEEN: 윈도우의 범위를 지정 (선택사항)
- 관련 문제 - 급여 상위 10%의 평균 나이
-
SELECT AVG(age) as avg_age #평균을 구해라 FROM ( SELECT *, NTILE(10) OVER (ORDER BY salary DESC) AS decile #급여 내림차순으로 10등분 하는데 FROM employees ) ranked WHERE decile = 1; #상위 10%인 것만 가져와서
-
- 관련 문제 - 제품별로 가장 최근 주문을 제외한 모든 주문을 구하기
-
SELECT order_id, product_id, order_date FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY product_id ORDER BY order_date DESC) #제품 아이디로 나눠서 주문날짜 최신순부터 랭킹을 매긴다. 동일값이 나와도 나온순서대로 고유 랭킹번호 부여 FROM orders ) ranked WHERE rn > 1; #랭킹이 1이 아닌것만 필터링
-
-
특히 어려웠던 것
- 파이썬 문제풀이
- 문제 카드 뭉치
- 카드더미, 인덱스
- 요구사항
- 카드더미에서 순서대로 꺼낸다.
- 그것이 goal과 맞는지 확인한다.
- 맞으면 yes, 아니면 no이다.
#요구사항을 해결하기위한 방법 #카드더미에서 순서대로 꺼낸다. -> 순서대로 꺼내는 것을 확인하깅 위해 각각 위치 변수를 지정 #그것이 goal과 맞는지 확인한다. -> goal에서 하나씩 꺼내서 비교, 그리고 맞으면 다음 위치로 이동해야 하니까 1씩 누적 # -> 이때 카드1과 카드2는 다른 위치 정보를 가지고 있어야 함. #맞으면 yes, 아니면 no def solution(cards1, cards2, goal): index1, index2 = 0, 0 #카드더미에서 지금 어디위치인지 나타내는 포인터, 할때마다 1씩 누적해서 다음 이동 for word in goal: #goal에 있는 모든 단어를 하나씪 순회 if index1 < len(cards1) and cards1[index1] == word: #len(cards1)이 3이면 인덱스 0, 1, 2 만 접근 즉 항상 길이보다 작아야 인덱스에 접근 가능함. index1 += 1 #맞으면 인덱스 하나 추가 elif index2 < len(cards2) and cards2[index2] == word: index2 += 1 #인덱스는 카드더미마다 다르게 가져가야 처음부터 순차적으로 접근 가능 else: return "No" #맞는게 없다면 그냥 no 뱉기 return "Yes"- 문제 풀이
- index1, index2 = 0, 0
- 각 카드 뭉치에서 지금 어디까지 사용했는지 나타내는 포인터 , 단어를 하나 꺼낼 때마다 다음으로 이동하도록 함
- index1 < len(cards1)
- 인덱스 오류를 방지하기 위한 조건
- word =cards[index1]과 같다면 해당카드 사용
- index += 1 카드사용했으니 다음 카드로 넘어가기 위해 포인터 증가
- 문제 카드 뭉치
- SQL 문제풀이
- 문제 Average Selling Price
- 정답
# Write your MySQL query statement below # 각 제품의 평균 가격을 구하기(소수점 둘째자리까지 반올림) # 판매된 제품이 없는 경우, 평균가격은 0으로 가정 # 판매날짜가 가격표 날짜에 포함되어 있는 것으로 조인하기 # 행끼리 곱해서 더하기 # 만약 판매리스트가 없다면 0으로 하기 (LEFT JOIN하고 NULL값에 0을 넣어야겠는걸?) SELECT P.product_id, ROUND(IFNULL(SUM(P.price*U.units)/ SUM(U.units), 0),2) AS average_price FROM Prices P LEFT JOIN UnitsSold U ON P.product_id = U.product_id AND U.purchase_date BETWEEN P.start_date AND P.end_date GROUP BY P.product_id;- 문제 구조화 / 해당하는 쿼리
- 각 제품의 평균 가격을 구하기(소수점 둘째자리까지 반올림) → gorup by, round(값, 2)
- 판매이력이 없는 경우, 평균가격은 0으로 가정 → 가격표를 기준으로 left join(판매 이력이 없는 것도 보이게) product_id 기준으로 묶기, 또한 해당 시기에 맞는 가격과 매칭되게 판매일이 start, end안에 포함되어야 있어야 함
- → ifnull(null값이면 , 0으로)
- 가격은 변동하고 있음 같은 제품이라도 가격테이블표에 따라 가격이 달라짐 (어떤 가격으로 계산되었는지 날짜를 잘 봐야함)
- 코드 한번 더 연습
-
SELECT P.product_id, ROUND(IFNULL(SUM(P.price * U.units) / SUM(U.units), 0), 2) AS average_price #각 가격에 판매량을 곱해서 평균을 내야 하기 때문에 AVG()는 사용못함 FROM Prices P LEFT JOIN UnitsSold U ON P.product_id = U.product_id AND U.purchase_date BETWEEN P.start_date AND P.end_date #판매일이 가격적용시점에 알맞게 매칭되도록 함 GROUP BY P.product_id
다음에 적용해 볼 것
- [ ] 위클리 파이썬 풀어봐야지~
'시각화' 카테고리의 다른 글
| 250730_태블로 기초, 파이썬(pop()) (5) | 2025.07.30 |
|---|