1. 동물의 아이디와 이름
SELECT ANIMAL_ID, NAME FROM ANIMAL_INS ORDER BY ANIMAL_ID ASC;
SQL
복사
2. 어린 동물 찾기
SELECT ANIMAL_ID, NAME FROM ANIMAL_INS WHERE INTAKE_CONDITION <> 'Aged';
SQL
복사
3. 아픈 동물 찾기
-- 코드를 입력하세요
SELECT ANIMAL_ID, NAME FROM ANIMAL_INS WHERE INTAKE_CONDITION = 'Sick';
SQL
복사
4. 이름이 없는 동물의 아이디
SELECT ANIMAL_ID FROM ANIMAL_INS WHERE NAME IS NULL;
SQL
복사
5. 여러 기준으로 정렬하기
SELECT ANIMAL_ID, NAME, DATETIME
FROM ANIMAL_INS
ORDER BY NAME ASC,
DATETIME DESC;
SQL
복사
6. 과일로 만든 아이스크림 고르기
SELECT F.FLAVOR
FROM FIRST_HALF AS F
JOIN ICECREAM_INFO AS I
ON I.FLAVOR = F.FLAVOR
WHERE F.TOTAL_ORDER > 3000
AND I.INGREDIENT_TYPE = 'fruit_based'
ORDER BY F.TOTAL_ORDER DESC;
SQL
복사
•
JOIN 키: 두 테이블 모두 FLAVOR가 키이므로 ON F.FLAVOR = I.FLAVOR.
•
필터 먼저: WHERE에서 주문량과 성분 조건으로 후보를 줄이고, 그다음 ORDER BY로 정렬.
•
출력 컬럼: 문제 요구는 맛 이름만이므로 F.FLAVOR만 선택. (주문량은 정렬용)
SELECT F.FLAVOR
FROM FIRST_HALF F
WHERE F.TOTAL_ORDER > 3000
AND EXISTS(
SELECT 1
FROM ICECREAM_INFO I
WHERE I.FLAVOR = F.FLAVOR
AND I.INGREDIENT_TYPE = 'fruit_based'
)
ORDER BY F.TOTAL_ORDER DESC;
SQL
복사
인덱스가 크면 도움:
•
ICECREAM_INFO (INGREDIENT_TYPE, FLAVOR) 또는 (FLAVOR)
•
FIRST_HALF (TOTAL_ORDER, FLAVOR) 혹은 (FLAVOR, TOTAL_ORDER)
실제 데이터 분포에 따라 선택.
코드 다시 보기
AND EXISTS (
SELECT 1
FROM ICECREAM_INFO I
WHERE I.FLAVOR = F.FLAVOR
AND I.INGREDIENT_TYPE = 'fruit_based'
)
SQL
복사
해석 과정
1.
바깥 쿼리(F)에서 한 줄씩 가져온다.
→ 즉, FIRST_HALF의 특정 맛(F.FLAVOR)을 잡고,
2.
서브쿼리 실행:
SELECT 1
FROM ICECREAM_INFO I
WHERE I.FLAVOR = F.FLAVOR
AND I.INGREDIENT_TYPE = 'fruit_based'
SQL
복사
→ ICECREAM_INFO에서 같은 맛이면서 성분이 fruit_based인 행을 찾는다.
3.
만약 그 조건을 만족하는 행이 1개라도 있다면 EXISTS(...)는 TRUE.
•
이 경우 바깥 쿼리의 F 행이 결과에 포함된다.
•
없다면 FALSE, 즉 제외된다.
SELECT 1은 왜 쓰는가?
•
EXISTS는 실제로 반환된 값에 관심 없고, 행이 존재하는지만 확인합니다.
•
그래서 SELECT * 대신 SELECT 1을 많이 씁니다. (관례 + 성능상 깔끔)
JOIN vs EXISTS 비교
•
JOIN: 두 테이블을 합쳐서 조건을 걸고 결과를 만든다.
•
EXISTS: 바깥 테이블 기준으로 "조건 만족하는 상대 테이블의 행이 있냐?"만 본다.
두 방법 다 답은 같지만:
•
EXISTS는 존재 여부만 확인 → 중복 걱정 없음.
•
JOIN은 조합된 행을 만들기 때문에, 조인된 결과 중복을 신경 써야 할 때가 있음.
7. 흉부외과 또는 일반외과 의사 목록 출력하기
SELECT
D.DR_NAME,
D.DR_ID,
D.MCDP_CD,
DATE_FORMAT(D.HIRE_YMD, '%Y-%m-%d') AS HIRE_YMD
FROM DOCTOR AS D
WHERE D.MCDP_CD IN ('CS', 'GS')
ORDER BY D.HIRE_YMD DESC, D.DR_NAME ASC;
SQL
복사
8. 12세 이하인 여자 환자 목록 출력하기
SELECT
P.PT_NAME,
P.PT_NO,
P.GEND_CD,
P.AGE,
IFNULL(P.TLNO, 'NONE') AS TLNO
FROM PATIENT P
WHERE P.AGE <= 12
AND P.GEND_CD = 'W'
ORDER BY P.AGE DESC, P.PT_NAME ASC;
SQL
복사
9. 인기있는 아이스크림
SELECT
F.FLAVOR
FROM FIRST_HALF F
ORDER BY F.TOTAL_ORDER DESC, F.SHIPMENT_ID ASC;
SQL
복사
10. 재구매가 일어난 상품과 회원 리스트 구하기
SELECT
OS.USER_ID,
OS.PRODUCT_ID
FROM ONLINE_SALE OS
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) >= 2
ORDER BY USER_ID ASC, PRODUCT_ID DESC;
SQL
복사
•
WHERE → 행 걸러내기
•
GROUP BY → 묶기
•
HAVING → 묶인 집합 걸러내기
11. 역순 정렬하기
SELECT
A.NAME, A.DATETIME
FROM ANIMAL_INS A
ORDER BY ANIMAL_ID DESC;
SQL
복사
12. 조건에 맞는 도서 리스트 출력하기
SELECT
B.BOOK_ID,
DATE_FORMAT(B.PUBLISHED_DATE, "%Y-%m-%d") AS PUBLISHED_DATE
FROM BOOK B
WHERE B.CATEGORY = '인문'
AND YEAR(PUBLISHED_DATE) = 2021
ORDER BY B.PUBLISHED_DATE ASC;
SQL
복사
13. 평균 일일 대여요금 구하기
-- 코드를 입력하세요
SELECT ROUND(AVG(DAILY_FEE), 0) AS AVERAGE_FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE = 'SUV';
SQL
복사
14. 강원도에 위치한 생산공장 목록 출력하기
-- 함수 적용이라 인덱스를 못 탈 수 있음.
SELECT
F.FACTORY_ID,
F.FACTORY_NAME,
F.ADDRESS
FROM FOOD_FACTORY F
WHERE LEFT(F.ADDRESS, 3) = '강원도'
ORDER BY FACTORY_ID;
-- LIKE로 해야 인덱스 적용이 가능
SELECT
F.FACTORY_ID,
F.FACTORY_NAME,
F.ADDRESS
FROM FOOD_FACTORY F
WHERE ADDRESS LIKE '강원도%'
ORDER BY FACTORY_ID;
SQL
복사
15. 모든 레코드 조회
SELECT * FROM ANIMAL_INS ORDER BY ANIMAL_ID;
SQL
복사
16. 상위 n개 레코드
SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME ASC
LIMIT 1;
== 여러 명인 경우를 고려 ==
SELECT NAME
FROM ANIMAL_INS
WHERE DATETIME = (SELECT MIN(DATETIME) FROM ANIMAL_INS);
SQL
복사
17. 조건에 맞는 회원수 구하기
SELECT COUNT(*) AS USERS
FROM USER_INFO
WHERE LEFT(JOINED, 4) = 2021
AND AGE BETWEEN 20 AND 29;
-- JOINED가 DATE 타입이라면 문자로 잘라 쓰는 대신 YEAR() 함수를 쓰는 게 더 직관적임
SELECT COUNT(*) AS USERS
FROM USER_INFO
WHERE YEAR(JOINED) = 2021
AND AGE BETWEEN 20 AND 29;
SQL
복사
18. 파이썬 개발자 찾기
SELECT
D.ID,
D.EMAIL,
D.FIRST_NAME,
D.LAST_NAME
FROM DEVELOPER_INFOS D
WHERE SKILL_1 = 'Python'
OR SKILL_2 = 'Python'
OR SKILL_3 = 'Python'
ORDER BY D.ID;
SQL
복사
19. 잔챙이 잡은 수 구하기
SELECT COUNT(*) AS FISH_COUNT
FROM FISH_INFO
WHERE LENGTH IS NULL;
SQL
복사
20. 가장 큰 물고기 10마리 구하기
SELECT ID, LENGTH
FROM FISH_INFO
WHERE LENGTH IS NOT NULL
ORDER BY LENGTH DESC, ID ASC LIMIT 10;
-- 백틱 활용: 컬럼명이 함수와 같은 경우
SELECT ID, `LENGTH`
FROM FISH_INFO
WHERE `LENGTH` IS NOT NULL
ORDER BY `LENGTH` DESC, ID ASC
LIMIT 10;
-- 윈도우 함수 활용
SELECT ID, `LENGTH`
FROM (
SELECT
ID,
`LENGTH`,
ROW_NUMBER() OVER (ORDER BY `LENGTH` DESC, ID ASC) AS rn
FROM FISH_INFO
WHERE `LENGTH` IS NOT NULL
) AS sub
WHERE rn <= 10;
SQL
복사
21. 이름이 있는 동물의 아이디
SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
ORDER BY ANIMAL_ID ASC;
SQL
복사
22. 나이 정보가 없는 회원 수 구하기
SELECT COUNT(*) AS USERS
FROM USER_INFO
WHERE AGE IS NULL
SQL
복사
23. 잡은 물고기의 평균 길이 구하기
SELECT ROUND(AVG(IFNULL(LENGTH, 10)), 2) AS AVERAGE_LENGTH
FROM FISH_INFO;
SQL
복사
24. 가장 비싼 상품 구하기
SELECT MAX(PRICE) AS MAX_PRICE FROM PRODUCT;
SQL
복사
25. 최댓값 구하기
SELECT MAX(DATETIME) AS 시간 FROM ANIMAL_INS;
SQL
복사
26. 잡은 물고기 중 가장 큰 물고기의 길이 구하기
SELECT CONCAT(MAX(LENGTH), 'cm') AS MAX_LENGTH
FROM FISH_INFO;
SQL
복사



