데이터 분석/SQL 36

[쉽게 쓴 SQL] FIRST_VALUE, LAST_VALUE 함수

특정 컬럼의 첫 번째, 혹은 마지막 값을 뽑고 싶다. 예제 세팅 글 각 제품 그룹에서 가장 낮은 값을 알고 싶다 - FIRST_VALUE SELECT a.product_name ,b.group_name ,a.price ,FIRST_VALUE (a.price) OVER (PARTITION BY b.group_name ORDER BY a.price) AS lowest_price_per_group FROM product a INNER JOIN product_group b ON (a.group_id = b.group_id); 그럼 가장 비싼 값을 알고 싶다면? SELECT a.product_name ,b.group_name ,a.price ,FIRST_VALUE (a.price) OVER (PARTITION B..

[쉽게 쓴 SQL] ROW_NUMBER, RANK, DENSE_RANK 차이

*dense : 빽빽한, 밀집한 세 개의 함수는 모두 순위를 매길 때 사용하지만, 조금씩의 차이가 있다. 예제 세팅 글 제품 가격이 낮은 순서로 순위를 매기고 싶다. 단, 같은 가격에도 순위 차이가 생기도록 한다. - ROW_NUMBER SELECT a.product_name ,b.group_name ,a.price ,ROW_NUMBER () OVER (PARTITION BY b.group_name ORDER BY a.price) FROM product a INNER JOIN product_group b ON (a.group_id = b.group_id); Postgresql에서는 같은 값을 가지는 ROW 중 ROW ID 가 높은 행이 우선 정렬된다 (desc 정렬에도 동일하다) = SELECT * FR..

[SQL 문법] AVG 함수

group_name 별 평균 가격을 알고 싶다 이전 글에서 준비한 product, product_group 테이블을 inner join 후 avg 함수 사용 SELECT a.group_name , avg(price) FROM product_group a INNER JOIN product b ON (a.group_id = b.group_id) GROUP BY a.group_name; 제품의 가격과 그 제품의 그룹 별 평균 가격을 같이 보고 싶다 이 때 분석함수를 사용 SELECT b.product_name , b.price , a.group_name , avg(b.price) OVER(PARTITION BY a.group_name) FROM product_group a INNER JOIN product b..

[SQL 문법] 분석 함수

집계의 결과와 테이블의 내용을 같이 보고 싶기 때문에 사용 실습 세팅 CREATE TABLE product_group ( group_id serial PRIMARY KEY, group_name varchar (255) NOT null ); CREATE TABLE product ( product_id serial PRIMARY KEY ,product_name varchar(255) NOT null ,price decimal (11,2) ,group_id int NOT null ,FOREIGN key(GROUP_id) REFERENCES product_group (group_id) ); INSERT INTO product_group (group_name) VALUES ('smartphone') ,('lapt..

[SQL 문법] CUBE () 절

다차원의 소계를 구한다 브랜드brand 별, 세그먼트segment 별 소계 및 전체 합계를 보고 싶다 역시 GRUOPING SETS로 아래와 같이 할 수 있다 SELECT brand, segment, sum(revenue) FROM sales_items GROUP BY GROUPING SETS ( (brand, segment), (brand), (segment), ()) ORDER BY brand, segment; 이를 쉽게 하는 방법이 CUBE() 절 SELECT brand, segment, sum(revenue) FROM sales_items GROUP BY CUBE (brand,segment) ORDER BY brand, segment; CUBE 절에 지정된 컬럼 수가 N개 면, 2의 N승 개의 레..

[SQL 문법] ROLLUP ( ) 절

GROUP BY를 한 컬럼을 기준으로 가능한 소계를 모두 보기 위해 사용한다 * roll up : 말아 올린다. * 소계 : 영어로 subtotal, 전체가 아닌 어느 한 부분만을 셈한 합계 (출처 : 네이버 사전) 브랜드를 기준으로 각 세그먼트의 소계 및 전체 합계를 보고 싶다 지난 글에서 했듯이 GROUPING SETS를 통해 할 수 있다 SELECT brand, segment, sum(revenue) FROM sales_items GROUP BY GROUPING SETS ( (brand,segment), (brand), ()) ORDER BY brand, segment; 이와 동일한 것이 ROLLUP SELECT brand, segment, sum(revenue) FROM sales_items GR..

[SQL 문법] GROUPING SET 절, GROUPING 함수

다양한 기준으로 집계함수(sum, count 등)를 사용하여 도출한 결과를 한 눈에 보려면 UNION ALL 을 써야 한다. 이것을 쉽게 정리할 수 있게 돕는다 판매 제품에 대한 테이블이 있다 CREATE TABLE sales_items ( brand varchar NOT NULL ,segment varchar NOT NULL ,revenue int NOT NULL ,primary KEY (brand, segment) ); INSERT INTO sales_items (brand, segment, revenue) VALUES ('abc', 'premium', 100) ,('abc','basic',200) ,('xyz','premium',100) ,('xyz', 'basic', 300) ; 브랜드 별, 세그..

[SQL 문법] HAVING

group by 를 사용하고 집계함수를 써 결과 값을 만들어 내는데, 그 결과 값을 필터링 하기 위함 where는 결과 이전을 필터링 하고 having은 그 이후를 필터링 구매량이 200 이상인 고객을 찾고 싶다 SELECT p.customer_id ,sum(p.amount) AS amount FROM payment p GROUP BY customer_id HAVING sum(p.amount) > 200 ORDER BY amount DESC; ORDER BY amount 는 됐는데, HAVING amount > 200 은 안됨. 구매량의 합이 190 이상인 고객이 이용한 매장을 알고 싶다 SELECT p.customer_id ,c.store_id ,sum(p.amount) AS amount FROM pa..

[SQL 문법] GROUP BY

특정 column 기준으로 그룹을 나눈다 payment 테이블에서 각 customer 만 뽑는다 SELECT p.customer_id FROM payment p GROUP BY p.customer_id ; 599건이 나옴. 전에 썼던 select distinct 로 활용 가능 SELECT DISTINCT p.customer_id FROM payment p ; 거래액이 가장 많은 고객 순으로 뽑고 싶다 SELECT p2.customer_id ,sum( p2.amount ) AS amount_sum FROM payment p2 GROUP BY p2.customer_id ORDER BY amount_sum DESC ; sum 함수 없이 쓰면 이런 오류가 나온다. *aggregate function : 집계함수..

[SQL 문법] NATURAL JOIN

자동으로 값의 일부가 같은 행을 묶어준다. 하지만 실무에서는 잘 쓰이지 않는다. 오류가 생길 수 있기 때문 우리가 natural join 에 기대하는 상황 CREATE TABLE CATEGORIES ( CATEGORY_ID SERIAL PRIMARY KEY ,CATEGORY_NAME VARCHAR (255) NOT NULL ); CREATE TABLE PRODUCTS ( PRODUCT_ID SERIAL PRIMARY KEY ,PRODUCT_NAME VARCHAR(255) NOT NULL ,CATEGORY_ID INT NOT NULL ,FOREIGN KEY (CATEGORY_ID) REFERENCES CATEGORIES (CATEGORY_ID) ); INSERT INTO CATEGORIES (CATEGOR..