https://school.programmers.co.kr/learn/courses/30/lessons/144856

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

1. author 테이블과 book 테이블 inner join

book_id, author_id, category, author_name, book.price 정보를 담은 테이블 출력

 

2. 1번 테이블과 book_sales 테이블 inner join 

 

3. 작가번호, 이름, 카테고리로 그룹화 후 price * sales 집계

 

select distinct a.author_id, a.author_name, category, sum(price*sales) as total_sales
from 
(
select book_id, author.author_id, category, author_name, book.price
from book inner join author
on book.author_id = author.author_id
) as a inner join book_sales as b
on a.book_id = b.book_id
where date_format(b.sales_date,'%Y-%m') = '2022-01'
group by author_id, author_name, category
order by a.author_id, category desc

https://school.programmers.co.kr/learn/courses/30/lessons/157339

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

조건을 살펴보면

 

1. 자동차 종류가 SUV, 세단

2. 2022-11-01~ 2022-11-30 사이의 대여 기록이 없고

3. 30일 대여 금액이 50만원 이상 200만원 미만

 

 

위 조건을 토대로

 

1. 2022-11-01~ 2022-11-30 사이에 대여 기록이 존재하는 car_id 목록을 가진 테이블 추출

 

2. 30일 이상 대여 시, 할인율 계산을 위해

car_rental_company_car 과 car_rental_company_discount_plan 테이블을 inner join

조인 조건은 car_type 이 일치하고 duration_type 이 '30일 이상'

 

3. where 조건절에서 1번 테이블의 목록에 있는 car_id 는 11-01 ~ 11-30 사이에 대여가 불가능하므로 not in 으로 제외

car_type 이 세단, SUV 이고, 대여 가격이 50만원 이상 200만원 미만일 때 

 

4. car_id, car_type, fee(대여 가격 계산 후 floor 로 소수점 제거) 출력

 

5. order by 로 fee, car_type, car_id 각각 내림차순, 오름차순, 내림차순으로 정렬

 

 

select car.car_id, car.car_type, floor(car.daily_fee * ((100-discount.discount_rate)/100) * 30) as fee
from car_rental_company_car as car inner join car_rental_company_discount_plan as discount
on car.car_type = discount.car_type and
discount.duration_type = '30일 이상'
where 
car_id not in
(
    select distinct car_id
    from car_rental_company_rental_history
    where end_date > '2022-11-01' and start_date < '2022-12-01'
    order by car_id
 )
and (car.car_type = 'SUV' or car.car_type = '세단')
and ((car.daily_fee * 30 * (1-(discount.discount_rate)/100)) between 500000 and 2000000)
order by car.daily_fee * 30 * (1-(discount.discount_rate)/100) desc, car.car_type asc, car.car_id desc

https://school.programmers.co.kr/learn/courses/30/lessons/131530

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

1. (price-price%10000) 으로 만원 단위로 그룹화

2. count 로 개수 출력

3. 그룹화 한 단위로 오름차순 정렬

 

select price- price%10000 as price_group,  count(*) as products
from product
group by price-price%10000
order by price-price%10000

https://school.programmers.co.kr/learn/courses/30/lessons/151141

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

1. car_rental_company_rental_history 테이블과 car_rental_company_car 테이블을 inner join

case 문으로 7일, 30일, 90일 이상의 값을 가진 duration 속성 출력 (7일 미만일 경우 null)

 

2. 1번에서 나온 테이블과 car_rental_company_discount_plan left outer join

duration 이 null 인 경우의 history 도 출력

 

3. case 문 한 번 더 써서 duration_type 이 null 인 경우는 daily_fee 와 date 를 곱하고

아닐 경우는 discount_rate 만큼의 할인이 적용된 가격 출력

 

select aa.history_id,
case
when duration_type is null then aa.daily_fee * date
else 
 floor((aa.daily_fee * date)-((aa.daily_fee * date) * discount_rate/100))
end as fee
from
(
    select car.car_id ,history.history_id, car.daily_fee as daily_fee, datediff(history.end_date, history.start_date)+1 as date,
    case
    when  datediff(history.end_date, history.start_date)+1 between 7 and 30 then '7일 이상'
    when datediff(history.end_date, history.start_date)+1 between 30 and 90 then '30일 이상'
    when datediff(history.end_date, history.start_date)+1 >= 90 then '90일 이상'
    end as duration
    from car_rental_company_car as car, car_rental_company_rental_history as history
    where car.car_id = history.car_id and car.car_type like '트럭'
) as aa
left outer join
car_rental_company_discount_plan as discount
on aa.duration = discount.duration_type and discount.car_type = '트럭'
order by fee desc, history.history_id desc

 

https://school.programmers.co.kr/learn/courses/30/lessons/59413

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

풀이

 

group by 로 간단하게 묶으면 될 것같지만, 조건에는 집계 결과가 0인 시간대도 출력해야 함

이를 위해 with recursive 재귀 쿼리를 사용

0 부터 1까지의 시간대별 데이터를 가진 hour 테이블을 animal_outs 테이블과 outer join

 

 

with recursive hourrange AS (
  select 0 AS hour
  union ALL
  select hour + 1
  from hourrange
  where hour < 23
)

select h.hour, count(animal_id)
from hourrange as h left outer join animal_outs as a
on h.hour = hour(a.datetime)
group by h.hour
order by h.hour;

https://school.programmers.co.kr/learn/courses/30/lessons/131532

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

매우 단순한 조인문제

두 테이블 조인 후, gender 가 null 이 아닌, user_id 를 distinct 로 중복 제거해서 카운트

 

 

select year(o.sales_date), month(o.sales_date) as month,u.gender as gender, count(distinct u.user_id) as users
from user_info as u inner join online_sale as o
on u.user_id = o.user_id and u.gender is not null
group by year(o.sales_date), month(o.sales_date), u.gender
order by year(o.sales_date), month(o.sales_date), u.gender

https://school.programmers.co.kr/learn/courses/30/lessons/62284

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

Milk, Yogurt 를 모두 담고있는 cart_id 를 출력하는 문제

 

1. Yogurt 를 담고 있는 카트 아이디 테이블 a

2. Milk 를 담고 있는 카트 아이디 테이블 b

3. a inner join b

4. cart_id 로 오름차순 정렬

 

select a.cart_id
from
(select cart_id, name
from cart_products
where name like 'Yogurt') as a,

(select cart_id, name
from cart_products
where name like 'Milk') as b

where a.cart_id = b.cart_id
order by a.cart_id

https://school.programmers.co.kr/learn/courses/30/lessons/157342

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

풀이

 

자동차 평균 대여 기간을 구하는 간단한 문제

 

 

1. 대여 기간 = datediff(end_date, start_date)+1

** 빌리는 당일도 대여 기간에 포함해야 하므로 1을 더해줘야 함

2. 대여기간의 평균 = avg(DATEDIFF(end_date, start_date)+1)

3. 대여기간의 평균에서 소수 둘 째 자리에서 반올림 = round(avg(DATEDIFF(end_date, start_date)+1), 1)

4. car_id 로 group by

5. 위 값 기준으로 내림차순, car_id 기준으로 내림차순

 

매우간단

 

select car_id, round(avg(DATEDIFF(end_date, start_date)+1), 1) as average_duration
from car_rental_company_rental_history
group by car_id
having round(avg(DATEDIFF(end_date, start_date)+1), 1) > 7
order by round(avg(DATEDIFF(end_date, start_date)+1), 1) desc, car_id desc;

https://school.programmers.co.kr/learn/courses/30/lessons/131534

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

풀이

위와 같은 테이블 구조에서

21년도 가입자의 연, 월 별 구매자 수와 구매자 비율을 구하는 문제

 

ONLINE_SALE 테이블의 user_id, sales_date

USER_INFO 테이블의 user_id, joined

 

 

1. sales_date 의 연도가 2021 인 USER_INFO 와 ONLINE_SALES 를 inner join

2. ONLINE_SALES 의 sales_date 연, 월로 group by

3. select 절에서 year, month 함수를 통해 sales_date 에서 각각 연, 월 출력

4.  21년 가입자 중, 22년 구매 내역이 있는 사용자의 조회를 위해 count 함수 사용

5. (4번 / USER_INFO 에서 가입년도가 2021인 유저의 수) 의 값을 구한 후 round 함수로 소수 첫번 째 자리까지 출력

 

여기서 주의해야 하는 점이 바로 중복되는 데이터

 

2021 년에 가입한 A 라는 사용자가

2022년 1월에 2번

2022년 2월에 1번 구매 내역이 있는 경우

월 별 구매 회원 수를 구해야 하기 때문에

1월, 2월 각각 1의 값 출력 필요

 

count 함수를 사용할 때 distinct 를 써서 같은 달에 여러 구매내역을 가진 유저의 중복을 제거

 

 

select year(sales_date) as year, month(sales_date) as month, count(distinct o.user_id) as puchased_users,
round(
count(distinct o.user_id)/
    (select count(*)
    from user_info  
    where year(joined) = 2021),1) as puchased_ratio
from user_info as u, online_sale as o
where u.user_id = o.user_id and year(u.joined) = 2021
group by year(sales_date), month(sales_date);

https://www.acmicpc.net/problem/11049

 

11049번: 행렬 곱셈 순서

첫째 줄에 입력으로 주어진 행렬을 곱하는데 필요한 곱셈 연산의 최솟값을 출력한다. 정답은 231-1 보다 작거나 같은 자연수이다. 또한, 최악의 순서로 연산해도 연산 횟수가 231-1보다 작거나 같

www.acmicpc.net

 

조건

 

주어진 행렬은 인접한 행렬끼리만 곱연산이 가능

 

 

풀이

 

n개의 행렬을 저장하고 있는 배열 input[][]

i ~ j 까지 곱연산의 최소 횟수를 저장하는 배열 dp[][]

 

 

우선 dp 배열의 값 초기화

 

i~i 의 곱연산 회수는 0이기 때문에 dp[i][j] = 0

i~ i+1 의 곱연산 횟수는 input[i][0] * input[i][1] * input[i+1][1]

그 외엔 Integer.MAX_VALUE 로

 

 

 

3중 반복문을 통해 간격, 시작점, 중간점을 탐색하며 값 삽입

 

i 는 간격

바로 다음 행렬의 곱연산 횟수는 위에 초기화에서 이미 설정해 주었기 때문

임의의 값 n 부터 n+2 까지의 행렬의 최소값을 구하기 위해 2부터 시작

 

j 는 시작점

입력값 처음부터 끝까지 탐색

 

k 는 중간점

시작점(j) ~ 시작점(j) + 간격(i) 의 곱연산 최소값을 구하기 위해 dp 배열에 저장되어있던 이전 값들을 활용

 

 

 

    public void solution11049() throws Exception{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(reader.readLine());

        int input[][] = new int[n][n];

        int dp[][] = new int[n][n];
        for(int i=0; i<n; i++){
            StringTokenizer st = new StringTokenizer(reader.readLine());

            input[i][0] = Integer.parseInt(st.nextToken());
            input[i][1] = Integer.parseInt(st.nextToken());
        }
        

        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){

                if(j==i)
                    dp[i][j]=0;
                else if(j==i+1)
                    dp[i][j] = input[i][0] * input[i][1] * input[j][1];
                else
                    dp[i][j] = Integer.MAX_VALUE;
            }
        }


        for(int i=2; i<n; i++){
            for(int j =0; j<n-i; j++){
                for(int k=j; k<j+i; k++){
                    int cnt = input[j][0] * input[k][1] * input[j+i][1];
                    dp[j][j+i] = Math.min(dp[j][j+i], dp[j][k] + dp[k+1][j+i] + cnt);
                }
            }
        }
        System.out.println(dp[0][n-1]);

    }

+ Recent posts