티스토리 뷰
기존 글에 추가할 검토용 보완 원고입니다.
수치가 달라서 다시 분석했다
AI가 만든 쿼리의 결과를 보고 데이터가 많이 다르다는 것을 발견했다. 내가 다시 분석해 보니, AI가 잘못 추론한 부분 때문에 수치가 잘못 나온 것이었다.
이때 문제를 찾는 출발점은 SQL이 실행되는지가 아니었다. 나온 숫자가 내가 확인하려는 업무의 결과와 맞는지를 보는 일이었다. AI가 만든 쿼리를 받았다고 검토가 끝난 것은 아니었다. 차이를 발견한 뒤 내가 다시 분석하는 과정이 필요했다.
이 경험에서 독자에게 남기고 싶은 기준은 간단하다. 쿼리가 실행됐다는 사실과 집계 결과가 맞다는 판단은 따로 확인해야 한다. 예상과 다른 숫자가 나오면, AI의 설명을 그대로 받아들이기 전에 무엇을 어떤 기준으로 계산했는지 다시 살펴봐야 한다.
다른 업무에 적용할 때는 다음 질문을 점검표로 사용할 수 있다. 이 목록은 당시 실제로 사용한 절차를 재현한 것이 아니라, 경험을 바탕으로 정리한 검토 질문이다.
- 내가 구하려는 값을 한 문장으로 설명할 수 있는가?
- AI가 그 값을 같은 의미로 해석했는가?
- 결과가 예상과 다를 때 차이가 나는 근거를 직접 확인했는가?
- 수정한 내용과 아직 확인하지 못한 부분을 구분했는가?
작은 예제로 조인 중복을 직접 확인하는 방법
아래는 당시 내부 데이터나 실제 쿼리를 공개한 것이 아니라, 집계 오류를 설명하기 위해 별도로 구성한 교육용 예제다. 업무상 사람 수를 세려는데 이력 행을 세면 어떤 차이가 생기는지 확인할 수 있다. 실제 사건의 원인이 반드시 이 예제와 같았다는 뜻은 아니다.
대상자는 1번과 2번 두 명이다. 1번에게 처리 이력 두 개, 2번에게 이력 한 개가 있다고 가정한다. 다음 SELECT는 테이블을 생성하거나 원본을 변경하지 않는다. VALUES를 사용하는 PostgreSQL·SQLite 계열 문법의 예제이며, 다른 DB에서는 해당 제품의 상수 행 작성 문법으로 바꿔야 한다.
WITH targets(id) AS (VALUES (1), (2)),
history(target_id, event_id) AS (VALUES (1, 101), (1, 102), (2, 103))
SELECT COUNT(*) AS joined_rows,
COUNT(DISTINCT t.id) AS people
FROM targets t
JOIN history h ON h.target_id = t.id;
계산 결과는 joined_rows=3, people=2다. COUNT(*)는 조인 결과의 행을 세므로 1번이 두 번 포함된다. 목적이 '이력이 하나 이상 있는 대상자 수'라면 대상자를 기준으로 EXISTS를 쓰는 방법도 있다.
WITH targets(id) AS (VALUES (1), (2)),
history(target_id, event_id) AS (VALUES (1, 101), (1, 102), (2, 103))
SELECT COUNT(*) AS people
FROM targets t
WHERE EXISTS (
SELECT 1 FROM history h WHERE h.target_id = t.id
);
이 쿼리는 people=2를 반환한다. 다만 DISTINCT를 붙이는 것만으로 모든 오류가 해결되지는 않는다. 금액 합계를 구할 때 중복을 없애거나, 서로 다른 신청을 한 사람의 행을 하나로 묶으면 오히려 필요한 자료를 잃을 수 있다. 먼저 집계 단위가 사람·신청·처리 이력 중 무엇인지 결정해야 한다.
보고서에 넣기 전 확인할 네 가지
- 기간의 시작·끝, 취소·중복·미완료 처리 규칙을 한 문장으로 적는다.
- 집계 전 대상 키와 원본 행을 조회하고, 조인 전후 행 수를 비교한다.
- 이력 없음·한 개·여러 개인 대상과 경계 날짜를 각각 확인한다.
- 검증한 SQL·조건·확인 시각을 함께 남긴다. 그 뒤 숫자를 보고서에 옮긴다.
공식 문서 확인(2026-10-12): PostgreSQL 조인, 집계 함수. 이 문서는 예제의 SQL 의미를 확인하는 참고 자료이며, 우리 업무의 집계 규칙을 대신 정해 주지는 않는다.
재현 확인: 2026-10-12 SQLite 3.53.1의 별도 메모리 DB에서 첫 예제 (3, 2), EXISTS 예제 2를 확인했다. 운영 DB나 실제 업무자료를 대상으로 실행한 결과는 아니다. 다음 검토에서는 업무의 집계 단위와 실제 테이블 관계를 먼저 기록한 뒤 이 비교 기준을 적용할 예정이다.
아래 그림은 SQL 결과를 대조하는 과정을 설명하기 위해 AI로 제작한 일러스트이며 실제 업무 화면이 아닙니다.

