'동일한' 회원이 '동일한' 상품을 재구매한 데이터를 추출.
USER_ID와 PRODUCT_ID가 겹치는 ROW를 추출해야 할 것.
구글링을 하다가 중복 값을 찾는 쿼리를 발견하고 일단 적용해봤는데, 정답이었다.
정답
SELECT
USER_ID,
PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID ASC, PRODUCT_ID DESC;
✅ GROUP BY 여러 컬럼: 어떻게 작동하나?
(USER_ID, PRODUCT_ID) 의 조합이 동일한 행들끼리 그룹화
한 회원이 같은 상품을 여러 번 구매했는지 파악 가능
✅ HAVING COUNT(* ) > 1의 역할
그룹별로 구매 횟수가 2번 이상인 경우만 필터링
왜 WHERE COUNT(B.WRITER_ID) >= 3 은 안될까?
COUNT는 그룹화된 결과를 만든 뒤에 계산됨.WHERE는 그룹화 전에 필터를 하므로 COUNT()가 동작하지 않는다| 구문 위치 | 역할 | 집계 함수 사용 가능 여부 |
|---|---|---|
WHERE | GROUP BY 이전에, 행 필터링 | ❌ COUNT(), SUM() 불가능 |
HAVING | GROUP BY 이후에, 그룹 필터링 | ✅ COUNT(), AVG() 등 가능 |
SELECT
U.USER_ID,
U.NICKNAME,
CONCAT(U.CITY,' ', U.STREET_ADDRESS1, ' ', U.STREET_ADDRESS2) AS '전체주소',
CONCAT(SUBSTR(TLNO, 1, 3),'-',SUBSTR(TLNO, 4, 4),'-',SUBSTR(TLNO, 8, 4)) AS '전화번호'
FROM USED_GOODS_BOARD B LEFT JOIN USED_GOODS_USER U
ON B.WRITER_ID = U.USER_ID
GROUP BY B.WRITER_ID
HAVING COUNT(B.WRITER_ID) >=3
ORDER BY USER_ID DESC;
자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기
일단 자동차 대여 기록을 보니, CAR_ID가 겹치는 경우가 많았다. 같은 자동차를 빌렸다가, 반납했다가, 빌렸다가 하니까 당연한 결과다.
그래서 이런 중복되는 값을 어떻게 처리할지가 포인트인 것 같다.
SELECT
CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE
=> 두 쿼리를 결합하자!
정답
SELECT
CAR_ID,
IF(
CAR_ID IN (
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE
),
'대여중',
'대여 가능'
) AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;
IF(조건, 참일 때 값, 거짓일 때 값)
일단 phone_number를 리스트로 만들고, for 반복문을 이용해 끝에서부터 4자리만 남기고 전부 *로 바꾸면 될 것 같다.
처음 작성한 코드
def solution(phone_number):
answer = list(phone_number)
for i in range(len(answer)-4):
answer[i] = '*'
answer = ''.join(answer)
return answer
''.join은 선택된 요소들을 하나로 이어주는 문법이다. ''안에 다른 문자나 공백을 넣ㅇ르 수도 있다.
조금 더 코드를 깨끗하게 만들 순 없을까?
반복문을 이용하지 않아도 될 것 같은데...
하는 마음에 replace를 사용해 보았다.
버전 1(오답)
solution(phone_number):
phone_number = phone_number.replace(phone_number[:-4], '*')
return phone_number
그런데 이러면 phone_number[:-4]까지 * 하나로 처리된다.
즉, '01033334444'를 입력하면 '* 4444'가 된다.
그렇다면 그냥 len(phone_number)-4 까지 다 '* '로 처리하고, phone_number[-4:]와 이어주는 건 어떨까?
버전 2(정답)
solution(phone_number):
phone_number = phone_number.replace(phone_number[:-4], '*')
return phone_number