도서/모두를 위한 postgreSQL

Day14. 다양한 상황에서의 데이터 결합

joje* 2023. 8. 13. 14:08

1. 그룹화 이후 데이터 결합하기

: union_example 데이터베이스에서 모든 상품의 평균 평점을 상품 이름, 상품 종류와 함께 출력한다고 가정하면 아래의 작업이 필요하다.

  • 평점 테이블을 상품 종류와 상품 이름으로 그룹화한다(GROUP BY)
  • 모든 상품을 하나의 테이블로 결합한다.(UNION)
  • 모든 상품 테이블과 평점 테이블을 결합한다(JOIN)

: 각 단계의 쿼리들은 아래와 같이 작성될 수 있다.

  • SELECT item_type, item_id, avg(rating.rating) AS rating FROM rating GROUP BY item_type, item_id;

 

  • (SELECT name, id AS item_id, 'drink' AS item_type FROM drink)
  • UNION ALL
  • (SELECT name, id AS item_id, 'ramen' AS item_type FROM ramen)
  • UNION ALL
  • (SELECT name, id AS item_id, 'canned_food' AS item_type FROM canned_food);

 

  • SELECT name, item_type, rating
  • FROM
  •   (
  •     SELECT item_type, item_id, avg(rating.rating) AS rating
  •     FROM rating
  •     GROUP BY item_type, item_id
  •   )rating
  • RIGHT JOIN 
  •   (
  •     (
  •        SELECT name,id AS item_id, 'drink' AS item_type
  •        FROM drink
  •     )UNION ALL
  •     (
  •        SELECT name,id AS item_id, 'ramen' AS item_type
  •        FROM ramen
  •     )UNION ALL
  •     (
  •       SELECT name,id AS item_id, 'canned_food' AS item_type
  •       FROM canned_food
  •     )
  •   )items
  • USING(item_id, item_type);

2. 내부조인

: 같은 테이블을 JOIN 하는 것을 내부 JOIN이라 한다.

: 다음 항목이 표시된 테이블을 출력하기 위해서는 

  • 매운 라면의 이름
  • 맵지 않은 라면의 이름
  • 세 종류의 상품의 평균 평점의 합

: 아래의 단계를 거쳐서 원하는 데이터의 값을 얻어올 수 있다.

  • 라면의 평균 평점이 적힌 표를 출력한다.(GROUP BY)
  • 라면의 정보와 평균 평점이 함께 적힌 표를 출력한다.(JOIN)
  • 매운 라면과 맵지 않은 라면이 조합된 적힌 표를 출력한다.

: 각 단계의 쿼리문은 아래와 같이 작성될 수 있다.

  • SELECT avg(rating.rating) AS avg_rating, item_type, item_id FROM rating WHERE item_type =' ramen' GROUP BY item_type, item_id;

 

  • SELECT ramen.name, ramen.id AS item_id, ramen.is_spicy, COALESCE(avg_rating,0) AS avg_rating
  • FROM(
  •   SELECT avg(rating.rating) AS avg_rating, item_type, item_id
  •   FROM rating
  •   WHERE item_type = 'ramen'
  •   GROUP BY item_type, item_id
  • ) r_rating RIGHT JOIN ramen
  • ON ramen.id = r_rating.item_id;

 

  • SELECT not_spicy.name AS not_spicy_name, spicy.name AS spicy_name, (not_spicy.avg_rating +spicy.avg_rating) AS avg_sum_rating
  • FROM(
  •   SELECT ramen.name, ramen.id AS item_id, ramen.is_spicy, COALESCE(avg_rating,0) AS avg_rating
  •    FROM(
  •       SELECT avg(rating.rating) AS avg_rating, item_type, item_id
  •       FROM rating
  •       WHERE item_type = 'ramen'
  •       GROUP BY item_type, item_id
  •    ) r_rating RIGHT JOIN ramen ON ramen.id = r_rating.item_id;
  •    WHERE ramen.is_spicy = FALSE
  • )not_spicy,(
  •   SELECT ramen.name, ramen.id AS item_id, ramen.is_spicy, COALESCE(avg_rating,0) AS avg_rating
  •    FROM(
  •       SELECT avg(rating.rating) AS avg_rating, item_type, item_id
  •       FROM rating
  •       WHERE item_type = 'ramen'
  •       GROUP BY item_type, item_id
  •    ) r_rating RIGHT JOIN ramen ON ramen.id = r_rating.item_id;
  •    WHERE ramen.is_spicy = TRUE
  • )spicy;