VB.NET이나 VBA에서는 값에 따라 분기할 때 습관처럼 If ... Then ... Else 를 쓰죠. SQL 안에서 같은 일을 하려면 보통 CASE WHEN 을 씁니다. 표준 SQL 문법이라 MySQL, MariaDB, SQL Server 어디로 옮겨도 그대로 돌아간다는 게 장점입니다.

이번 경우는 발주번호 테이블에서 가장 작은 번호를 보고, 거기서 1을 뺀 값이 0보다 크면 0을, 0 이하이면 그 값을 그대로 받는 쿼리입니다. 제목은 "MIN 값"이라고 했지만 실제 비교 대상은 MIN(발주번호) - 1 이라는 점을 먼저 짚어 둡니다.

SELECT
    CASE
        WHEN MIN(`발주번호`) - 1 > 0
        THEN 0
        ELSE MIN(`발주번호`) - 1
    END AS V
FROM `order_delivery_number`
WHERE 1

실행하면 결과 열 V 하나에 값 한 줄이 나옵니다.

CASE WHEN 쿼리 실행 결과로 V 컬럼 값이 표시된 화면

이 쿼리가 하는 일을 숫자로 따라가 보면

발주번호가 모두 양수(예: 최솟값 100)라면 100 - 1 = 99 이고 0보다 크니까 결과는 0입니다. 반대로 테이블에 이미 0이나 음수 번호가 섞여 있어서 최솟값이 -3이라면 -3 - 1 = -4 가 되고, 0보다 크지 않으니 -4가 그대로 나옵니다.

결국 결과는 항상 0 이하이고, 이미 음수가 있으면 거기서 하나 더 작은 값이 됩니다. 정식 번호와 겹치지 않는 임시 번호를 음수로 하나씩 내려가며 발급하는 식의 용도에 맞는 패턴입니다. 결과가 0이 나왔다면 아직 음수 번호가 하나도 없다는 뜻이니, 실제 발급할 때는 그 상황을 어떻게 처리할지(0을 쓸지, -1부터 시작할지) 프로그램 쪽에서 한 번 더 정해 줘야 합니다.

WHERE 1 은 조건이 항상 참이라 사실상 없는 것과 같습니다. 프로그램에서 조건을 AND ... 로 이어 붙이기 편하게 자리만 잡아 둔 형태로, PHP로 동적 쿼리를 만들 때 자주 보이는 습관이죠.

IF()나 LEAST()로 짧게 쓰기

MySQL에는 엑셀의 IF와 비슷한 IF(조건, 참일때, 거짓일때) 함수도 있어서 같은 쿼리를 이렇게 줄일 수 있습니다.

SELECT IF(MIN(`발주번호`) - 1 > 0, 0, MIN(`발주번호`) - 1) AS V
FROM `order_delivery_number`;

조건 자체가 "0과 비교해서 작은 쪽"이니 LEAST() 를 쓰면 더 간단해집니다.

SELECT LEAST(MIN(`발주번호`) - 1, 0) AS V
FROM `order_delivery_number`;

세 쿼리 모두 결과는 같습니다. 다만 IF() 는 MySQL 계열 전용이라 다른 DB로 옮길 가능성이 있으면 CASE WHEN 쪽이 무난합니다.

한 가지 조심할 점은 테이블이 비어 있을 때입니다. 행이 하나도 없으면 MIN() 이 NULL을 돌려주고, NULL과의 비교는 참이 아니라서 ELSE 쪽으로 빠져 결과도 NULL이 됩니다. VB.NET에서 이 값을 CInt() 로 바로 바꾸면 DBNull 변환 오류가 나니, 빈 테이블에서도 0을 받고 싶다면 아래처럼 NULL을 먼저 막아 두는 게 편합니다.

SELECT LEAST(COALESCE(MIN(`발주번호`), 1) - 1, 0) AS V
FROM `order_delivery_number`;