- 오늘 진행한 일
1. SQL 코드카타 복습
2. 알고리즘 코드카타 복습
- 기억할 내용
SQL
만원 단위 가격대 별로 나누어주기
TRUNCATE(컬럼,-4)
만원 단위이기 때문에 정수자리 뒤에서 4번째를 떼어준다
*TRUNCATE 는 정해주는 자릿수만큼 버려준다
- 를 붙일 경우 정수뒷자리에서부터 버려준다
TRUNCATE(1234.567,1)
>> 1234.5
TRUNCATE(1234.567,2)
>> 1234.56
TRUNCATE(1234.567,-1)
>> 1230
TRUNCATE(1234.567,-2)
>> 1200
음식종류별로 즐겨찾기수가 가장 많은 식당 찾기
음식종류별로 그룹화를 했는데 즐겨찾기 수가 가장 많은 곳의 음식점을 출력해야했다
SELECT food_type, rest_id,rest_name,max(favorites)
FROM rest_info
WHERE (rest_id,rest_name) IN
(SELECT rest_id,rest_name
FROM rest_info)
GROUP BY food_type
ORDER BY 1 DESC
서브쿼리를 써야하는 건 알겠는데
어떤 정보값을 뽑아줘야하는지가 너무 헷갈렸음..
위와 같이 쿼리를 짜면 그냥 rest_id 와 rest_name 의 임의의 값을 출력해준다
우연히 결괏값은 동일 했으나
내가 출력하고자 하는 것은 각 음식종류별로 즐겨찾기수가 가장 많은 식당의 정보들이므로
음식종류와, 즐겨찾기수가 많은 식당을 먼저 그룹화를 해주어야 한다
select food_type,rest_id,rest_name,favorites
from rest_info
where (food_type,favorites) in
(
select food_type,max(favorites)
from rest_info
group by 1
)
order by 1 DESC
이렇게 쿼리를 짜게 될 경우
food_type 과 favorites 에는 각 음식종류와 가장 많은 즐겨찾기 수를 가지고 있는
rest_id 와 rest_name 이 들어가게 된다
서브쿼리가 아직 익숙해지지 않으니 더 자주 복습해야겠다!
IF절에서 IN 과 =
SELECT car_id
, IF(car_id =
(SELECT car_id
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE<='2022-10-16'AND END_DATE>='2022-10-16'),'대여중','대여 가능') AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;
위와 같이 쿼리를 작성했더니 오류가 발생했다
Subquery returns more than 1 row
서브쿼리에서 1개 이상의 값이 반환이 될때 발생하는 오류이다.
서브쿼리의 결괏값이 다중행이라면 다중행 연산자를 사용해주어야 한다
IN | 임의의 값과 일치 |
ANY | 어느 하나의 값이라도 만족 |
ALL | 모든 값에 만족 |
EXISTS | 만족하는 값이 존재하는지 여부를 확인 |
내가 출력하고 싶은 결과는 '10월16일의 car_id 와 일치 한다면' 이기 때문에 IN 을 사용해서 해결했다
SELECT car_id
, IF(car_id IN
(SELECT car_id
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE<='2022-10-16'AND END_DATE>='2022-10-16'),'대여중','대여 가능') AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;
WHRER 절에서 서브쿼리
host_id 가 2건 이상인 id 와 name, host_id 를 구하는 문제였다.
SELECT id
, name
, host_id
FROM places
WHERE (id,name) IN (
SELECT host_id
FROM places
GROUP BY host_id
HAVING COUNT(host_id)>=2
)
결과는 오류
Operand should contain 2 column(s)
컬럼의 수가 일치 하지 않을 때 발생 하는 오류이다.
왼쪽은 2개의 컬럼이지만 오른쪽의 서브쿼리의 결과가 1개이기 때문에 발생했다.
위에서의 문제는 음식종류와 즐겨찾기 두가지가 다 일치해야하므로 2개를 작성했지만
이번 문제에서는 host_id 값만 일치하면 되는 문제였다
SELECT id
, name
, host_id
FROM places
WHERE host_id IN (
SELECT host_id
FROM places
GROUP BY host_id
HAVING COUNT(host_id)>=2
)
내가 원했던 host_id 값을 입력하여 해결했다
한 행에 1개의 정보만 있는 컬럼에서 2개 이상 출력하기
SELECT cart_id
FROM cart_products
WHERE cart_id IN
(
SELECT cart_id
FROM CART_PRODUCTS
WHERE name IN ('Milk','Yogurt')
)
GROUP BY cart_id
HAVING COUNT(cart_id)>=2
ORDER BY 1
name 컬럼 안에 1개씩 데이터가 들어가 있기 때문에
서브쿼리를 사용해서 milk 또는 yogurt 값이 들어가 있는 cart_id 를 찾고
찾은 cart_id 값을 그룹화 해서 그룹화한 cart_id 값이 2건 이상 일때를 찾았는데..
저 값이 들어가 있는 cart_id 를 그룹화 하고
전체 데이터에서 cart_id 가 2개 이상일때를 찾아주는 값이 나온 것 같다
group by 를 제대로 이해하지 못한듯 하다 ㅠㅜ
왜 저런 결과가 나왔는지 매니저님께 여쭤봤으니 답이 오면 꼭 정독해보기!
A. where 절에서 나온 값으로 그룹화를 해주고 싶었지만
이렇게 쿼리를 짤 경우 서브쿼리로 찾은 cart_id를 전체데이터 기준으로 그룹화를 해준다..
그렇기 때문에 milk 와 yogurt 만 있는 cart_id 가 아니라 두개중 하나의 값을 포함한
cart_id의 전체갯수를 세어준다!!
사실상
SELECT cart_id
FROM CART_PRODUCTS
WHERE name IN ('Milk','Yogurt')
GROUP BY cart_id
HAVING COUNT(cart_id)>=2
ORDER BY 1
이렇게 서브쿼리를 제외한 결과와도 동일한 것...
where 절에서 출력한 모든 행의 값을 그룹화 하는 것이 아니라
뽑은 cart_id 의 전체데이터를 그룹화 해주는 것이었다.
내가 생각한 것처럼 milk 와 yogurt 가 포함된 cart_id 를 뽑고 싶다면
SELECT cart_id
FROM CART_PRODUCTS
WHERE name IN ('Milk','Yogurt')
GROUP BY cart_id
HAVING COUNT(DISTINCT name)=2
ORDER BY 1
그룹화한 cart_id 에서 중복되지 않는 이름이 2건일때
즉 milk 와 yogurt 가 같이 있을 때 를 뽑는 식으로 쿼리를 짜주어야한다.
* 만약 중복되는 이름을 제외해주지 않는다면
milk 가 2개 이거나 yogurt 가2 개인 경우만을 출력해주니
꼭 중복값을 제외해주어야 한다
SELECT cart_id
FROM CART_PRODUCTS
WHERE name = 'Milk' AND cart_id IN (
select cart_id
from cart_products
where name = 'Yogurt')
GROUP BY cart_id
ORDER BY 1
이런 방식으로 name 이 milk 인 cart_id 와 yogurt 인 cart_id 를 찾는 것도 방법이다.
- 내일 진행 예정
1. ADSP 복습
2. 통계분석 - 기초통계
3. SQL 코드카타
'TIL' 카테고리의 다른 글
2024-04-09 (0) | 2024.04.09 |
---|---|
2024-04-08 (0) | 2024.04.08 |
2024-04-04 (0) | 2024.04.04 |
2024-04-03 (0) | 2024.04.03 |
2024-04-02 (0) | 2024.04.02 |