디비를 사용하다보면 중복제거, 통계, 인덱싱 등의 작업을 자주 하게 됩니다.
방식이 여러가지니 제대로 이해 하지 못하고 사용하시는 분들도 많죠
이 글에선 세가지(DISTINCT, GROUP BY, WITH)의 방식을 소개 합니다.
중복된 행을 제거하고 "고유한 값"만 필요할때 사용합니다.
CREATE TABLE Employees (
EmployeeID INT,
EmployeeName VARCHAR(50),
DepartmentID INT
);
INSERT INTO Employees (EmployeeID, EmployeeName, DepartmentID) VALUES
(1, 'Alice', 10),
(2, 'Bob', 20),
(3, 'Charlie', 10),
(4, 'David', 20),
(5, 'Eve', 30),
(6, 'Frank', 10);
-- 중복된 DepartmentID 제거
SELECT DISTINCT DepartmentID
FROM Employees;
DepartmentID
------------
10
20
30
집계나 요약 할때 사용합니다.
특징 - 순서 보장 X (group하지 않은 여러개의 데이터도 조회를 해야할때(최신데이터 등) 순서를 보장하지 않기 때문에 원하지 않은 값이 나온다.)
-- DepartmentID별 직원 수 집계
SELECT DepartmentID, COUNT(*)
FROM Employees
GROUP BY DepartmentID;
DepartmentID | COUNT(*)
-------------|---------
10 | 3
20 | 2
30 | 1
서브쿼리를 저장해서 재사용이 가능하게 한다.
중복제거를 한 데이터를 조회할때 정렬이 가능하다 (최신데이터 등)
with join_table as (
select a.*, seq*price as tot_amt, b.co_cd
from receipts a
join companies b on a.cust_id = b.district
)
select '001&003' as co_cd, sum(tot_amt) as tot_amt
from join_table
where co_cd in ('001', '003')
group by 1
union all
select '002&004' as co_cd, sum(tot_amt) as tot_amt
from join_table
where co_cd in ('002', '004')
group by 1
최신데이터를 기준으로 rnk 즉 랭크를 매기고, 이에 대한 데이터를 순차조회 하는 방법입니다.
WITH RankedElements AS (
SELECT
element,
errorMsg,
occurTime, -- 나머지 컬럼들을 포함합니다
ROW_NUMBER() OVER (PARTITION BY element ORDER BY occurTime DESC) AS rnk
FROM tErrorReport
)
SELECT
element,
errorMsg,
occurTime -- 나머지 컬럼들을 포함합니다
FROM
RankedElements
WHERE
rnk = 1
ORDER BY
occurTime DESC
LIMIT 20;
element | errorMsg | occurTime
-------------|---------
10 | 3 | 최신
20 | 2 | 최신
30 | 1 | 최신