스테이킹 정산 목록에 필터를 걸어 나온 결과의 검증을 요청받았다. COUNT(*) 는 관리 화면과 쿼리가 맞았고 그것으로 끝낼 수도 있었다.
Table of contents
Open Table of contents
판단 기준 — 카운트만 대조했으면
건수가 같으면 대체로 통과로 본다. 그런데 건수는 몇 개인지만 말하고 무엇을 셌는지는 말하지 않는다.
두 가지 방법이 있었다. COUNT(*) 만 맞추고 끝내는 것과, 개수와 함께 머리글과 LIMIT 20 으로 상위 몇 행을 같이 뽑는 것이다. 뒤쪽을 골랐다. 이유는 이 목록으로 일괄 처리를 한다고 들었기 때문이다. 대신 검증마다 몇 분이 더 드는 것을 감수했다. 그 몇 줄이 이 검증의 결론을 바꿨다.
검증 — 샘플 행이 드러낸 정의 차이
상위 행의 profit_amount 가 전부 양수였고 fail_reason 은 전부 BELOW_MIN 이었다. 필터 이름에 마이너스 수익이 적혀 있는데 음수가 한 건도 없었다.
정의를 확인하니 수익률 미달은 profit_rate < MIN_RATE 인 건 전체이고 마이너스 수익은 그중 profit_rate < 0 인 건이었다. 뒤쪽이 앞쪽의 부분집합이었다.
원인 — 필터 이름이 합친 두 집합
화면 필터 이름에 둘이 나란히 적혀 있어서 합집합으로 읽혔다. 실제 WHERE 는 profit_rate < MIN_RATE 하나였고 마이너스는 그 안에 포함될 뿐이었다.
그러면 결과 건수는 기준 미달의 개수이지 마이너스의 개수가 아니다. 마이너스가 몇 건인지는 이 화면으로는 알 수 없었다.
기본 정렬이 감춘 구간
상위 몇 행에 음수가 없었던 것은 기본 정렬이 ORDER BY profit_rate 가 아니라 ORDER BY created_at 이었기 때문이다. profit_rate ASC 였으면 음수가 맨 위에 왔을 것이다.
정렬 기준 하나가 무엇이 먼저 보이는지를 정하고 그것이 검증의 결과까지 바꾼다. 마이너스만 추리려면 profit_rate 로 정렬해 음수 구간을 별도로 집계해야 했다.
대상 정의가 처리 결과를 바꾼다
이 목록으로 강제 만기 정산 같은 일괄 처리를 한다는 것이 이 구분을 중요하게 만들었다. 마이너스만 대상으로 알고 기준 미달 전체를 처리하면 이익이 나는 건까지 함께 정산된다.
같은 개수인데 다른 것을 세고 있을 수 있으므로 목록 검증을 COUNT(*) 와 머리글과 샘플 행 셋으로 하게 바꿨다. 회원 잔고에 직결되는 일괄 처리에서는 두 정의를 반드시 나눠 확인한다고 절차에 적었다.
정리
- 기준 미달과 음수는 다른 집합이고 뒤쪽이 부분집합이다
- 필터 이름에 둘이 적혀 있어도 실제
WHERE는 하나일 수 있다 - 건수는 몇 개인지만 말하고 무엇을 셌는지는 말하지 않는다
- 같은 개수인데 다른 것을 세고 있을 수 있다
- 기본 정렬이 값 순이 아니면 해당 구간이 상위에 안 뜬다
ORDER BY기준 하나가 검증의 결과를 바꾼다- 목록 검증은
COUNT(*)와 머리글과 샘플 행으로 한다 - 대상 정의가 틀리면 일괄 처리가 의도와 다른 결과를 낸다