TIL

2024-04-05

여연찌 2024. 4. 5. 17:54
  • 오늘 진행한 일

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