오답정리

sungsimdangmascot·2026년 5월 5일

1. ANY 연산자와 데이터 타입

질문: DBMS에서 ANY는 숫자만 입력할 수 있는가?

설명:
아니다. ANY 연산자는 숫자뿐만 아니라 문자열이나 날짜 등 비교가 가능한 모든 데이터 타입에 사용할 수 있다. 문자의 경우 가나다순이나 알파벳순으로 크기를 비교하게 되며, 날짜의 경우 과거와 미래를 기준으로 크기를 비교한다. 숫자에서만 쓰이는 문법이 아니다.


2. 서브쿼리(다중쿼리)의 이해

질문: 다중쿼리가 도대체 무엇이고 왜 이해가 안 가는가?

설명:
다중쿼리(정확한 명칭은 서브쿼리)는 쉽게 말해 '질문 안의 질문'이다.
수학에서 괄호 ( ) 안에 있는 식을 먼저 계산하고 그 결과를 바깥 계산에 쓰는 것과 똑같다.

SELECT * FROM player WHERE height > (SELECT height FROM player WHERE name = '홍길동');

이 쿼리에서 데이터베이스는 먼저 괄호 안의 서브쿼리를 실행해서 '홍길동의 키'를 찾는다. 만약 그 결과가 170이라면, 바깥 쿼리는 WHERE height > 170으로 변해서 키가 170보다 큰 사람들을 찾게 되는 원리이다. 이렇게 쿼리를 두 번 나누어 쓰지 않고 한 번에 처리하기 위해 서브쿼리를 사용한다.


3. ANY와 MAX의 차이, 그리고 출력 결과

문제 상황:
"K07팀 공격수(FW) 중 누구보다도 키가 큰 선수를 조회하라." 라는 문제에서 아래와 같은 쿼리를 작성했다.

SELECT player_name, height, team_id
FROM player
WHERE height > ANY (
    SELECT height
    FROM player
    WHERE team_id = 'K07' AND position = 'FW'
)
ORDER BY height;

질문 3-1: 가장 큰 사람을 물어봤는데 왜 MAX를 사용하지 않는가?
질문 3-2: 가장 큰 사람 한 명만 부르라는 것 같은데, 왜 여러 명이 큰 순서대로 나오는가?
질문 3-3: > ANY (SELECT MAX(height)...) 이렇게 쓰면 안 되는가?

설명:
이 문제는 한국어 해석과 SQL 문법의 특징 때문에 혼란이 온 것이다.

첫째, "선수를"이라고 해서 무조건 결과가 한 명이어야 하는 것은 아니다. 수학 문제에서 "방정식을 만족하는 x를 구하시오"라고 했을 때 답이 여러 개일 수 있는 것과 같다. 데이터베이스는 조건을 만족하는 '모든' 데이터를 가져온다.

둘째, SQL에서 > ANY는 서브쿼리 결과 중 "최솟값보다 큰 데이터"를 모두 찾는다는 뜻이다. 만약 K07팀 공격수들의 키가 170, 180, 190이라면, ANY는 "이 세 숫자 중 아무거나 하나보다 크면 합격"이라는 뜻이 된다. 즉, 가장 작은 170보다만 크면 171도, 180도 모두 정답으로 출력된다.

만약 출제자의 의도가 K07팀의 가장 큰 선수(190)보다도 더 큰 사람을 찾는 것이었다면 > ALL을 쓰거나, 서브쿼리에 MAX를 쓰는 것이 맞다. 하지만 이 문제는 SQL 자격증이나 학교 시험에서 ANY의 기능(최솟값보다 큰 것을 찾음)을 수험생이 아는지 테스트하기 위해 의도적으로 낸 문제일 확률이 높다.

셋째, > ANY (SELECT MAX(height)...)처럼 쓰면 문법적으로 오류가 나지는 않지만, 매우 어색한 코드가 된다. MAX를 쓰면 서브쿼리의 결과가 어차피 단 한 개(최댓값)만 나오게 된다. 결과가 한 개뿐인데 "그중 아무거나"를 뜻하는 ANY를 붙이는 것은 의미가 없으므로, 이럴 때는 그냥 > (SELECT MAX(height)...)처럼 부등호만 쓰는 것이 올바른 방법이다.


4. WHERE 조건과 HAVING 조건

질문: WHERE team_id = 'K07' AND position = 'FW'에서 AND 말고 HAVING을 쓰면 안 되는가?

설명:
안 된다. WHEREHAVING은 데이터를 걸러낸다는 점에서는 비슷하지만, 쓰는 타이밍이 완전히 다르다.

  • WHERE: 창고(테이블)에서 데이터를 처음 꺼내올 때 검사소 역할을 한다. "K07팀이고 공격수인 사람만 나와!" 하고 처음부터 걸러내는 것이다.
  • HAVING: 데이터를 꺼내온 뒤에, GROUP BY라는 문법을 써서 그룹으로 묶었을 때만 쓴다. 예를 들어 "팀별 평균 키를 구했는데, 그 평균 키가 180 이상인 팀만 남겨라" 할 때 쓴다.

이 쿼리에서는 데이터를 그룹으로 묶는 작업(GROUP BY)이 없으므로 무조건 WHERE 안에서 AND로 조건들을 연결해야 한다.


5. IN 연산자의 역할

질문: IN은 왜 들어가는가?

설명:
IN은 서브쿼리나 여러 개의 값 목록 중에서 "일치하는 것이 하나라도 있는지" 확인할 때 쓴다.

예를 들어 WHERE team_id = 'K01' OR team_id = 'K02' OR team_id = 'K03'이라고 쓰면 코드가 너무 길어진다. 이를 WHERE team_id IN ('K01', 'K02', 'K03')으로 짧고 알아보기 쉽게 줄여주는 문법이다. IN= ANY와 완벽하게 똑같은 역할을 한다고 기억하면 쉽다.


6. 제약조건 (CONSTRAINT)과 외래키(FOREIGN KEY)

문제 상황:
(오타 해석: "채ㅜㄴㅅㄱ먀ㅜㅅrk anjdi" -> "constraint가 뭐야")

CONSTRAINT pk_student PRIMARY KEY(student_id),
CONSTRAINT fk_student FOREIGN KEY(school_id) REFERENCES school(school_id)

-- 정상 데이터
INSERT INTO student VALUES(1, '김철수', 17, 1); 

-- 오류 발생 데이터
INSERT INTO student VALUES(2, '짱구', 15, 5); 

질문 6-1: CONSTRAINT가 무엇인가?
질문 6-2: 짱구 데이터를 넣을 때 오류가 나는 이유는 무엇인가?

설명:
CONSTRAINT(제약조건)는 데이터베이스에 쓰레기 데이터가 들어오지 못하게 막는 엄격한 '규칙'이다.

코드를 보면 학생 테이블에 FOREIGN KEY(외래키)라는 규칙이 걸려 있다. 이 규칙의 의미는 "학생 테이블에 학교 번호를 적으려면, 그 번호는 반드시 학교 테이블에 실제로 존재하는 번호여야 한다"는 것이다.

현재 학교 테이블(school)에는 1번 학교(DBMS학교)와 2번 학교(Java학교)밖에 없다. 그런데 짱구를 입력할 때 학교 번호로 '5'를 넣으려고 시도했다. 데이터베이스 입장에서는 "존재하지도 않는 5번 유령 학교에 학생을 넣을 수 없다"며 외래키 규칙 위반으로 저장을 거부(오류 발생)한 것이다.


7. NULL 데이터의 처리

질문: 서브쿼리 + ALL을 사용하여 최대 키를 비교하는 문제에서 height IS NOT NULL은 왜 쓰고 어떤 의미인가?

설명:
데이터베이스에서 NULL은 숫자 0이나 빈 칸이 아니라 "데이터가 아예 입력되지 않아서 알 수 없음"을 뜻한다.

만약 어떤 선수의 키가 기록되지 않아서 NULL 상태라고 가정해 보자. 키가 180인 선수와 알 수 없는 선수(NULL)를 비교하면, 데이터베이스는 누가 더 큰지 판단할 수 없어서 오류를 내거나 전체 쿼리 결과를 엉망으로 만든다.

특히 ALL 연산자를 쓸 때는 "모든 선수들의 키"와 비교를 해야 하는데, 그중에 NULL이 하나라도 끼어 있으면 비교 자체가 멈춰버리거나 아무런 결과도 나오지 않게 된다.

따라서 WHERE height IS NOT NULL이라는 조건을 달아서 "키 데이터가 제대로 입력된 사람들만 데리고 와서 비교하겠다"라고 안전장치를 걸어두는 것이다.

profile
성심당마스코트

0개의 댓글