예제 3: 레스토랑 예약 시스템
-- Customers 테이블 생성
-- 식당의 고객 정보를 저장합니다.
-- 고객의 고유 식별자, 이름, 전화번호, 이메일 주소가 포함됩니다.
CREATE TABLE Customers (
);
-- Tables 테이블 생성
-- 식당의 테이블 정보를 관리합니다.
-- 각 테이블은 고유 식별자와 수용 가능한 최대 인원 수를 가집니다.
CREATE TABLE Tables (
);
-- Reservations 테이블 생성
-- 고객의 테이블 예약 정보를 기록합니다.
-- 예약 ID, 고객 ID, 테이블 ID, 예약 시간 등의 정보를 포함하며, 예약은 특정 고객과 테이블에 연결됩니다.
CREATE TABLE Reservations (
);
-- Orders 테이블 생성
-- 각 예약 동안 발생한 주문을 추적합니다.
-- 주문 ID, 예약 ID(옵션), 주문 시간을 기록합니다.
CREATE TABLE Orders (
);
-- MenuItems 테이블 생성
-- 메뉴 아이템에 대한 정보를 저장합니다.
-- 메뉴 아이템의 고유 ID, 이름, 설명, 가격이 포함됩니다.
CREATE TABLE MenuItems (
);
-- OrderDetails 테이블 생성
-- 주문 상세 정보를 기록합니다.
-- 각 주문의 상세한 아이템과 수량 정보가 저장됩니다.
CREATE TABLE OrderDetails (
);
모델링 및 더미데이터
-- Customers 테이블 생성
-- 식당의 고객 정보를 저장합니다.
-- 고객의 고유 식별자, 이름, 전화번호, 이메일 주소가 포함됩니다.
CREATE TABLE Customers (
customer_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
phone_number VARCHAR(15),
email VARCHAR(100)
);
-- Tables 테이블 생성
-- 식당의 테이블 정보를 관리합니다.
-- 각 테이블은 고유 식별자와 수용 가능한 최대 인원 수를 가집니다.
CREATE TABLE Tables (
table_id INT AUTO_INCREMENT PRIMARY KEY,
capacity INT NOT NULL
);
-- Reservations 테이블 생성
-- 고객의 테이블 예약 정보를 기록합니다.
-- 예약 ID, 고객 ID, 테이블 ID, 예약 시간 등의 정보를 포함하며, 예약은 특정 고객과 테이블에 연결됩니다.
CREATE TABLE Reservations (
reservation_id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT,
table_id INT,
reservation_time DATETIME NOT NULL,
FOREIGN KEY (customer_id) REFERENCES Customers(customer_id),
FOREIGN KEY (table_id) REFERENCES Tables(table_id)
);
-- Orders 테이블 생성
-- 각 예약 동안 발생한 주문을 추적합니다.
-- 주문 ID, 예약 ID(옵션), 주문 시간을 기록합니다.
CREATE TABLE Orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
reservation_id INT,
FOREIGN KEY (reservation_id) REFERENCES Reservations(reservation_id),
order_time DATETIME NOT NULL
);
-- MenuItems 테이블 생성
-- 메뉴 아이템에 대한 정보를 저장합니다.
-- 메뉴 아이템의 고유 ID, 이름, 설명, 가격이 포함됩니다.
CREATE TABLE MenuItems (
menu_item_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
price INT NOT NULL
);
-- OrderDetails 테이블 생성
-- 주문 상세 정보를 기록합니다.
-- 각 주문의 상세한 아이템과 수량 정보가 저장됩니다.
CREATE TABLE OrderDetails (
order_detail_id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
menu_item_id INT,
quantity INT NOT NULL,
FOREIGN KEY (order_id) REFERENCES Orders(order_id),
FOREIGN KEY (menu_item_id) REFERENCES MenuItems (menu_item_id)
);
-- Customers 테이블에 더미 데이터 추가
INSERT INTO Customers (name, phone_number, email) VALUES
('홍길동', '010-1234-5678', 'hong@domain.com'),
('김민수', '010-2345-6789', 'minsu@domain.com'),
('이하나', '010-3456-7890', 'hana@domain.com'),
('최예진', '010-4567-8901', 'yejin@domain.com'),
('박지원', '010-5678-9012', 'jiwon@domain.com'),
('정수민', '010-6789-0123', 'sumin@domain.com'),
('유진아', '010-7890-1234', 'jina@domain.com'),
('남지현', '010-8901-2345', 'jihyun@domain.com'),
('오혜진', '010-9012-3456', 'hyejin@domain.com'),
('한예슬', '010-0123-4567', 'yesul@domain.com');
-- Tables 테이블에 더미 데이터 추가
INSERT INTO Tables (capacity) VALUES
(2), (4), (4), (2), (6),
(6), (8), (8), (10), (10);
-- Reservations 테이블에 더미 데이터 추가
INSERT INTO Reservations (customer_id, table_id, reservation_time) VALUES
(1, 1, '2024-05-01 18:00:00'),
(2, 2, '2024-05-02 18:00:00'),
(3, 3, '2024-05-03 18:00:00'),
(4, 4, '2024-05-04 18:00:00'),
(5, 5, '2024-05-05 18:00:00'),
(6, 6, '2024-05-06 18:00:00'),
(7, 7, '2024-05-07 18:00:00'),
(8, 8, '2024-05-08 18:00:00'),
(9, 9, '2024-05-09 18:00:00'),
(10, 10, '2024-05-10 18:00:00');
-- Orders 테이블에 더미 데이터 추가
INSERT INTO Orders (reservation_id, order_time) VALUES
(1, '2024-05-01 18:30:00'),
(2, '2024-05-02 18:30:00'),
(3, '2024-05-03 18:30:00'),
(4, '2024-05-04 18:30:00'),
(5, '2024-05-05 18:30:00'),
(6, '2024-05-06 18:30:00'),
(7, '2024-05-07 18:30:00'),
(8, '2024-05-08 18:30:00'),
(9, '2024-05-09 18:30:00'),
(10, '2024-05-10 18:30:00');
-- MenuItems 테이블에 더미 데이터 추가
INSERT INTO MenuItems (name, description, price) VALUES
('스테이크', '최고급 소고기 스테이크', 30000),
('파스타', '이탈리안 스타일 파스타', 15000),
('샐러드', '신선한 채소 샐러드', 12000),
('피자', '마르게리타 피자', 20000),
('치킨', '후라이드 치킨', 18000),
('타코', '멕시칸 스타일 타코', 16000),
('리조또', '버섯 리조또', 17000),
('수프', '양송이 크림 수프', 8000),
('빵', '신선한 구운 빵', 5000),
('와인', '고급 레드 와인', 40000);
-- OrderDetails 테이블에 더미 데이터 추가
INSERT INTO OrderDetails (order_id, menu_item_id, quantity) VALUES
(1, 1, 2),
(2, 2, 2),
(3, 3, 3),
(4, 4, 1),
(5, 5, 2),
(6, 6, 3),
(7, 7, 1),
(8, 8, 4),
(9, 9, 2),
(10, 10, 1);
문제
초급
- 문제: 식당 데이터베이스의 모든 고객 정보를 조회하세요. (이름, 전화번호, 이메일)
- 문제: 특정 고객(예: 홍길동)의 모든 예약 정보를 조회하세요.
- 문제: 특정 날짜(예: 2024년 5월 10일)의 모든 예약 정보를 조회하세요.
- 문제: 가장 인원 수용이 큰 테이블의 모든 정보를 조회하세요.
- 문제: 특정 메뉴 아이템(예: 스테이크)의 설명을 업데이트하세요.
- 문제: 특정 예약(예: 예약 ID가 5)에 속한 모든 주문을 조회하세요.
중급
- 문제: 각 테이블별로 몇 번 예약되었는지 집계하세요.
- 문제: 모든 메뉴 아이템의 평균 가격을 계산하세요.
- 문제: 각 고객별로 몇 번 예약했는지 집계하세요.
고급 (복잡한 조인 및 서브쿼리)
- 문제: 가장 많은 예약을 한 고객의 이름과 그 예약 수를 조회하세요.
- 문제: 특정 기간 동안의 총 예약 수를 계산하세요. (예: 2024년 5월 1일부터 5월 31일까지)
- 문제: 최근 예약된 순으로 고객 목록을 출력하세요.
- 문제: 특정 고객(예: 고객 ID가 3)의 총 주문 금액을 계산하세요.
- 문제: 모든 메뉴 아이템 중 가장 비싼 아이템을 찾으세요.
- 문제: 최대 주문 금액을 가진 예약 찾기 : 각 예약에 대한 총 주문 금액을 계산하고, 그 중에서 최대 금액을 가진 예약의 ID와 금액을 조회하세요.
- 문제: 모든 주문에서 가장 많이 주문된 메뉴 아이템의 이름과 총 주문 수량을 조회하세요.
- 문제: 2024년 5월 10일에 가장 많이 예약된 테이블의 ID와 예약 횟수를 조회하세요.
- 문제: 각 고객별로 모든 주문에 대한 평균 주문 금액을 계산하세요.
- 문제: 가장 많은 종류의 다른 메뉴 아이템을 주문한 고객의 이름과 주문한 메뉴 아이템의 수를 조회하세요.
개인적인 풀이
-- 초급 1번
SELECT c.name, c.phone_number, c.email
FROM Customers c;
-- 초급 2번
SELECT r.*
FROM Reservations r
JOIN Customers c
ON c.customer_id = r.customer_id
WHERE c.name = '홍길동';
-- 초급 3번
SELECT r.*
FROM Reservations r
WHERE DATE(reservation_time) = '2024-05-10';
-- 초급 4번
SELECT t.*
FROM Tables t
ORDER BY t.capacity DESC
LIMIT 1;
-- 초급 5번
UPDATE MenuItems
SET MenuItems.description = '고기가 부드러워요.'
WHERE MenuItems.name = '스테이크';
-- 초급 6번
SELECT o.*
FROM Orders o
JOIN Reservations r
ON r.reservation_id = o.order_id
WHERE o.reservation_id = 5;
-- 중급 1번
SELECT t.table_id, COUNT(r.table_id)
FROM Reservations r
JOIN Tables t
ON t.table_id = r.table_id
GROUP BY t.table_id;
-- 중급 2번
SELECT AVG(m.price)
FROM MenuItems m;
-- 중급 3번
SELECT c.name, COUNT(r.customer_id)
FROM Customers c
LEFT JOIN Reservations r
ON r.customer_id = c.customer_id
GROUP BY c.name;
-- 고급 1번
SELECT c.name, COUNT(r.customer_id)
FROM Customers c
JOIN Reservations r
ON r.customer_id = c.customer_id
GROUP BY c.name
ORDER BY COUNT(r.customer_id) DESC
LIMIT 1;
-- 고급 2번
SELECT COUNT(r.reservation_id)
FROM Reservations r
WHERE reservation_time BETWEEN '2024-05-01' AND '2024-05-31';
-- 고급 3번
SELECT c.name, r.reservation_time
FROM Customers c
JOIN Reservations r
ON r.customer_id = c.customer_id
ORDER BY r.reservation_time DESC;
-- 고급 4번
SELECT SUM(m.price * od.quantity)
FROM MenuItems m
JOIN OrderDetails od
ON od.menu_item_id = m.menu_item_id
JOIN Orders o
ON o.order_id = od.order_id
JOIN Reservations r
ON r.reservation_id = o.reservation_id
JOIN Customers c
ON c.customer_id = r.customer_id
WHERE c.customer_id = 3;
-- 고급 5번
SELECT m.name
FROM MenuItems m
WHERE m.price = (SELECT MAX(m.price) FROM MenuItems m);
-- 고급 6번
SELECT r.reservation_id, SUM(m.price * od.quantity) AS cnt
FROM Reservations r
JOIN Orders o
ON o.reservation_id = r.reservation_id
JOIN OrderDetails od
ON od.order_id = o.order_id
JOIN MenuItems m
ON m.menu_item_id = od.menu_item_id
GROUP BY r.reservation_id
ORDER BY cnt DESC
LIMIT 1;
-- 고급 7번
SELECT mi.name, SUM(od.quantity)
FROM MenuItems mi
JOIN OrderDetails od
ON od.menu_item_id = mi.menu_item_id
GROUP BY mi.name
ORDER BY SUM(od.quantity) DESC
LIMIT 1;
SELECT mi.name, sum(od.quantity) as total_ordered
FROM MenuItems as mi
JOIN OrderDetails od
ON od.menu_item_id = mi.menu_item_id
GROUP BY mi.name
HAVING total_ordered = (
SELECT max(qt) FROM (
SELECT sum(od.quantity) as qt
FROM OrderDetails od
GROUP BY menu_item_id
) as sq
);
-- 고급 8번
SELECT t.table_id, COUNT(r.reservation_id)
FROM Tables t
JOIN Reservations r
ON r.table_id = t.table_id
WHERE DATE(r.reservation_time) = '2024-05-10'
GROUP BY t.table_id
ORDER BY COUNT(r.reservation_id) DESC
LIMIT 1;
SELECT t.table_id, COUNT(r.reservation_id) as cnt
FROM Tables t
JOIN Reservations r
ON r.table_id = t.table_id
WHERE DATE(r.reservation_time) = '2024-05-10'
GROUP BY t.table_id
HAVING cnt = (
SELECT MAX(cnt2) FROM (
SELECT COUNT(r.reservation_id) as cnt2
FROM Reservations r
GROUP BY table_id
) as sq
);
-- 고급 9번
SELECT c.name, COALESCE(AVG(mi.price * od.quantity), 0)
FROM Customers c
LEFT JOIN Reservations r
ON r.customer_id = c.customer_id
LEFT JOIN Orders o
ON o.reservation_id = r.reservation_id
LEFT JOIN OrderDetails od
ON od.order_id = o.order_id
LEFT JOIN MenuItems mi
ON mi.menu_item_id = od.menu_item_id
GROUP BY c.name;
-- 고급 10번
SELECT DISTINCT c.name, COUNT(mi.menu_item_id) AS cont
FROM Customers c
JOIN Reservations r
ON r.customer_id = c.customer_id
JOIN Orders o
ON o.reservation_id = r.reservation_id
JOIN OrderDetails od
ON od.order_id = o.order_id
JOIN MenuItems mi
ON mi.menu_item_id = od.menu_item_id
GROUP BY c.name
HAVING cont = (
SELECT MAX(cnt) FROM(
SELECT COUNT(mi.menu_item_id) as cnt
FROM MenuItems mi
JOIN OrderDetails od
ON od.menu_item_id = mi.menu_item_id
JOIN Orders o
ON o.order_id = od.order_id
JOIN Reservations r
ON r.reservation_id = o.reservation_id
JOIN Customers c
ON c.customer_id = r.customer_id
GROUP BY c.name
) as sq
);
'코딩공부' 카테고리의 다른 글
| SQL 사무용품 관리 시스템 예제 (0) | 2024.05.10 |
|---|---|
| SQL 호텔예약시스템 예제 기록 (0) | 2024.05.09 |
| SQL 서브쿼리, GROUP BY, ORDER BY, LIMIT 간단 (0) | 2024.05.07 |
| Java NumberFormatException e 에 대한 정리 (0) | 2024.05.07 |
| Database SQL 기본문법 정리 (0) | 2024.05.02 |