문제 1: 고객과 그들의 첫 번째 대여 정보 조회
고객의 이름(first_name, last_name)과
그들이 대여한 첫 번째 영화의 제목(title)을 조회하세요.
--1
select first_name,last_name,title
from customer c
inner join rental r
on c.customer_id = r.customer_id
inner join inventory i
on r.inventory_id = i.inventory_id
inner join film f
on i.film_id = f.film_id;
--2
SELECT c.customer_id, r.inventory_id, MIN(rental_date) AS first_rental_date
FROM customer c
INNER JOIN rental r ON c.customer_id = r.customer_id
inner join inventory i
on r.inventory_id = i.inventory_id
inner join film f
on i.film_id = f.film_id
GROUP BY c.customer_id, r.inventory_id;
--정답
SELECT DISTINCT ON (c.customer_id) c.first_name, c.last_name, f.title
FROM customer c
INNER JOIN rental r ON c.customer_id = r.customer_id
INNER JOIN inventory i ON r.inventory_id = i.inventory_id
INNER JOIN film f ON i.film_id = f.film_id
ORDER BY c.customer_id, r.rental_date ASC;
위 쿼리에서 DISTINCT ON (c.customer_id) 부분은
DISTINCT ON 키워드를 사용하여
특정 열 또는 열의 조합에 대해 중복을 제거하는데 사용됩니다.
여기서 DISTINCT ON (c.customer_id)는
customer_id 열의 값이 달라질 때마다 결과를 반환하도록 합니다.
따라서 결과에는 각각의 고객에 대해 중복되지 않는
첫 번째 customer_id 값만 포함됩니다.
이후의 first_name, last_name, title 열은
해당 customer_id에 대한 값들 중 어떤 것을 반환할지를 결정하는데 사용될 것입니다.
이것은 PostgreSQL에서 제공하는 유용한 기능 중 하나입니다.
특히, 특정 그룹 내에서 중복된 값이 아닌 첫 번째 값을 선택하는데 유용합니다.
문제 2: 배우가 출연한 첫 번째 영화 조회
배우의 이름(first_name, last_name)과
그들이 출연한 첫 번째 영화의 제목(title)을 조회하세요.
select distinct on (a.actor_id) a.first_name, a.last_name,f.title
from actor a
inner join film_actor fa using (actor_id)
inner join film f using (film_id)
order by a.actor_id,fa.last_update asc;
--정답1
SELECT distinct on (a.actor_id) a.first_name, a.last_name, f.title
FROM actor a
INNER JOIN film_actor fa ON a.actor_id = fa.actor_id
INNER JOIN film f ON fa.film_id = f.film_id
ORDER BY a.actor_id ASC;
--정답2
SELECT distinct on (a.actor_id) a.first_name, a.last_name, f.title
FROM actor a
INNER JOIN film_actor fa ON a.actor_id = fa.actor_id
INNER JOIN film f ON fa.film_id = f.film_id;
order by를 쓰지 않아도 결과에는 변함이 없음
이미 오름차순으로 정렬이 되어있어서?
문제 3: 특정 고객이 대여한 모든 영화 조회
고객의 이름이 'Mary Smith'인 고객이
대여한 모든 영화의 제목(title)을 조회하세요.
select f.title
from rental r
inner join inventory i using (inventory_id)
inner join film f using (film_id)
inner join customer c using (customer_id)
where c.first_name = 'Mary' and c.last_name ='Smith';
--답안
SELECT f.title
FROM customer c
INNER JOIN rental r ON c.customer_id = r.customer_id
INNER JOIN inventory i ON r.inventory_id = i.inventory_id
INNER JOIN film f ON i.film_id = f.film_id
WHERE c.first_name = 'Mary' AND c.last_name = 'Smith';
문제 4: 특정 카테고리 영화의 배우 조회
'Comedy' 카테고리에 속하는 영화에
출연한 배우의 이름(first_name, last_name)을 조회하세요.
select a.first_name,a.last_name
from film_actor fa
inner join actor a using (actor_id)
inner join film f using (film_id)
inner join film_category fc using (film_id)
inner join category c using (category_id)
where c.name = 'Comedy';
--답안
SELECT DISTINCT a.first_name, a.last_name
FROM actor a
INNER JOIN film_actor fa ON a.actor_id = fa.actor_id
INNER JOIN film f ON fa.film_id = f.film_id
INNER JOIN film_category fc ON f.film_id = fc.film_id
INNER JOIN category c ON fc.category_id = c.category_id
WHERE c.name = 'Comedy';
film_actor에 같은 사람이 여러번 중복되어있기 때문에 DISTINCT를 사용해야함
문제 5: 특정 배우가 출연한 영화의 카테고리 조회
'Anne Cronyn'라는 이름의 배우가 출연한
영화의 카테고리를 조회하세요.
중복된 카테고리 이름은 한 번만 나타나야 합니다.
select distinct c.name
from film f
inner join film_actor fa using (film_id)
inner join actor a using (actor_id)
inner join film_category fc using (film_id)
inner join category c using (category_id)
where a.first_name = 'Anne' and a.last_name = 'Cronyn';
--답안
SELECT DISTINCT c.name
FROM category c
INNER JOIN film_category fc ON c.category_id = fc.category_id
INNER JOIN film f ON fc.film_id = f.film_id
INNER JOIN film_actor fa ON f.film_id = fa.film_id
INNER JOIN actor a ON fa.actor_id = a.actor_id
WHERE a.first_name = 'Anne' AND a.last_name = 'Cronyn';
결과가 같음