diff --git a/query.md b/query.md new file mode 100644 index 00000000..73406725 --- /dev/null +++ b/query.md @@ -0,0 +1,845 @@ +## Auth + +**로그인** + +```sql +-- 회원 + +-- 이메일로 회원 조회 +SELECT + u.id +FROM + users u +WHERE + u.email = ? + LIMIT 1; + +-- 연락처로 회원 조회 +SELECT + u.id +FROM + users u +WHERE + u.phone = ? + LIMIT 1; + +-- 회원 추가 +INSERT INTO users ( + created_at, created_by, email, name, password, phone, region_code, + status, updated_at, updated_by, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ); + +-- 회원 상태 이력 추가 +INSERT INTO user_status_history ( + created_at, created_by, reason, status, updated_at, updated_by, + user_id, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ? + ); +``` + +### Payment + +**결제 승인 & 저장** + +```sql +-- 결제 정보 추가 +INSERT INTO payment ( approved_at, method, order_id, payment_key, requested_at, reservation_id, status, total_amount, type, id +) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); + +-- 결제 상세 정보 추가 +INSERT INTO payment_detail ( payment_id, supplied_amount, vat, id +) VALUES ( ?, ?, ?, ? +); +-- 카드 결제 상세 정보 추가 +INSERT INTO payment_card_detail ( amount, approval_number, card_number, card_type, easypay_discount_amount, easypay_provider_code, installment_plan_months, is_interest_free, issuer_code, owner_type, id +) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +**결제 취소** + +SQL + +```sql +-- 예약 ID로 결제 정보 조회 +SELECT + p.id, + p.approved_at, + p.method, + p.order_id, + p.payment_key, + p.requested_at, + p.reservation_id, + p.status, + p.total_amount, + p.type +FROM + payment p +WHERE + p.reservation_id = ?; + +-- 추가 +-- 취소된 결제 정보 추가 +INSERT INTO canceled_payment ( + cancel_amount, cancel_reason, canceled_at, canceled_by, + card_discount_amount, easypay_discount_amount, payment_id, + requested_at, transfer_discount_amount, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +### Region + +**모든 시/도 조회** + +```sql +SELECT DISTINCT + r.sido_code, + r.sido_name +FROM + region r +ORDER BY + r.sido_name; +``` + +**시/군/구 조회** + +```sql +SELECT + r.sigungu_code, + r.sigungu_name +FROM + region r +WHERE + r.sido_code = ? +GROUP BY + r.sigungu_code, r.sigungu_name +ORDER BY + r.sigungu_name; +``` + +**지역 코드 조회** + +```sql +SELECT + r.code +FROM + region r +WHERE + r.sido_code = ? AND r.sigungu_code = ?; +``` + +### Reservation + +**Pending 예약 생성** + +```sql +-- schedule 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- theme 조회 +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t +WHERE + t.id = ?; + +-- 예약 추가 +INSERT INTO reservation ( + created_at, created_by, participant_count, requirement, + reserver_contact, reserver_name, schedule_id, status, + updated_at, updated_by, user_id, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +**확정** + +```sql +-- 예약 조회 +SELECT + r.id, r.created_at, r.created_by, r.participant_count, r.requirement, + r.reserver_contact, r.reserver_name, r.schedule_id, r.status, + r.updated_at, r.updated_by, r.user_id +FROM + reservation r +WHERE + r.id = ?; + +-- 일정 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- 예약 확정 +UPDATE + reservation +SET + participant_count = ?, requirement = ?, reserver_contact = ?, + reserver_name = ?, schedule_id = ?, status = ?, + updated_at = ?, updated_by = ?, user_id = ? +WHERE + id = ?; + +-- Schedule 확정 +UPDATE + schedule +SET + date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, + updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +**취소** + +```sql +-- 예약 조회 +SELECT + r.id, r.created_at, r.created_by, r.participant_count, r.requirement, + r.reserver_contact, r.reserver_name, r.schedule_id, r.status, + r.updated_at, r.updated_by, r.user_id +FROM + reservation r +WHERE + r.id = ?; + +-- 일정 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- 취소 예약 추가 +INSERT INTO canceled_reservation ( + cancel_reason, canceled_at, canceled_by, + reservation_id, status, id +) VALUES ( + ?, ?, ?, ?, ?, ? +); + +-- 예약 취소 +UPDATE + reservation +SET + participant_count = ?, requirement = ?, reserver_contact = ?, + reserver_name = ?, schedule_id = ?, status = ?, + updated_at = ?, updated_by = ?, user_id = ? +WHERE + id = ?; + +-- 일정 활성화 +UPDATE + schedule +SET + date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, + updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +**회원 예약 조회** + +```sql +-- 예약 조회 +SELECT + r.id, r.created_at, r.created_by, r.participant_count, r.requirement, + r.reserver_contact, r.reserver_name, r.schedule_id, r.status, + r.updated_at, r.updated_by, r.user_id +FROM + reservation r +WHERE + r.user_id = ? AND r.status IN (?, ?); + +-- 일정 조회 -> 각 예약별 1개씩(N개) +SELECT + s.id, + st.id AS store_id, + st.name AS store_name, + s.date, + s.time, + t.id AS theme_id, + t.name AS theme_name, + t.difficulty, + t.available_minutes, + s.status +FROM + schedule s + JOIN theme t ON t.id = s.theme_id + JOIN store st ON st.id = s.store_id +WHERE + s.id = ?; +``` + +**예약 상세 조회** + +```sql +-- 예약 조회 +SELECT + r.id, r.created_at, r.created_by, r.participant_count, r.requirement, + r.reserver_contact, r.reserver_name, r.schedule_id, r.status, + r.updated_at, r.updated_by, r.user_id +FROM + reservation r +WHERE + r.id = ?; + +-- 회원 연락처 정보 조회 +SELECT + u.id, u.created_at, u.created_by, u.email, u.name, u.password, + u.phone, u.region_code, u.status, u.updated_at, u.updated_by +FROM + users u +WHERE + u.id = ?; + +-- 결제 정보 조회 +SELECT + p.id, p.approved_at, p.method, p.order_id, p.payment_key, + p.requested_at, p.reservation_id, p.status, p.total_amount, p.type +FROM + payment p +WHERE + p.reservation_id = ?; + +-- 결제 상세 정보 조회 +SELECT + pd.id, + CASE + WHEN pbt.id IS NOT NULL THEN 1 -- bank_transfer + WHEN pcd.id IS NOT NULL THEN 2 -- card + WHEN pep.id IS NOT NULL THEN 3 -- easypay + WHEN pd.id IS NOT NULL THEN 0 -- etc + END AS payment_type, + pd.payment_id, pd.supplied_amount, pd.vat, + pbt.bank_code, pbt.settlement_status, + pcd.amount, pcd.approval_number, pcd.card_number, pcd.card_type, + pcd.easypay_discount_amount, pcd.easypay_provider_code, + pcd.installment_plan_months, pcd.is_interest_free, pcd.issuer_code, + pcd.owner_type, + pep.amount AS easypay_amount, + pep.discount_amount AS easypay_discount_amount, + pep.easypay_provider_code AS easypay_provider +FROM + payment_detail pd + LEFT JOIN payment_bank_transfer_detail pbt ON pd.id = pbt.id + LEFT JOIN payment_card_detail pcd ON pd.id = pcd.id + LEFT JOIN payment_easypay_prepaid_detail pep ON pd.id = pep.id +WHERE + pd.payment_id = ?; + +-- 취소 결제 정보 조회 +SELECT + cp.id, cp.cancel_amount, cp.cancel_reason, cp.canceled_at, + cp.canceled_by, cp.card_discount_amount, cp.easypay_discount_amount, + cp.payment_id, cp.requested_at, cp.transfer_discount_amount +FROM + canceled_payment cp +WHERE + cp.payment_id = ?; +``` + +### Schedule + +**날짜, 시간, 테마로 조회** + +```sql +SELECT + s.id, + st.id AS store_id, + st.name AS store_name, + s.date, + s.time, + t.id AS theme_id, + t.name AS theme_name, + t.difficulty, + t.available_minutes, + s.status +FROM + schedule s + JOIN theme t ON t.id = s.theme_id AND (? IS NULL OR t.id = ?) + JOIN store st ON st.id = s.store_id AND st.id = ? +WHERE + s.date = ? +``` + +**감사 정보 조회** + +```sql +-- 일정 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- 작업자 조회(createdBy, updatedBy) +SELECT + a.id, a.account, a.created_at, a.created_by, a.name, a.password, + a.permission_level, a.phone, a.store_id, a.type, a.updated_at, + a.updated_by +FROM + admin a +WHERE + a.id = ?; +``` + +**일정 생성** + +```sql +-- 날짜, 시간, 테마가 같은 일정 존재 여부 확인 +SELECT EXISTS ( + SELECT 1 + FROM schedule s + WHERE + s.store_id = ? + AND s.date = ? + AND s.theme_id = ? + AND s.time = ? +); + +-- 시간이 겹치는 같은 날의 일정이 있는지 확인 +SELECT + s.id, + st.id AS store_id, + st.name AS store_name, + s.date, + s.time, + t.id AS theme_id, + t.name AS theme_name, + t.difficulty, + t.available_minutes, + s.status +FROM + schedule s + JOIN theme t ON t.id = s.theme_id AND (? IS NULL OR s.theme_id = ?) + JOIN store st ON st.id = s.store_id AND st.id = ? +WHERE + s.date = ? + +-- 일정 추가 +INSERT INTO schedule ( + created_at, created_by, date, status, store_id, + theme_id, time, updated_at, updated_by, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +**일정 수정** + +```sql +-- 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- 수정 +UPDATE + schedule +SET + date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, + updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +**일정 삭제** + +```sql +-- 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- 삭제 +DELETE FROM schedule +WHERE id = ?; +``` + +**상태 → HOLD 변경** + +```sql +-- 조회 +SELECT + s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, + s.theme_id, s.time, s.updated_at, s.updated_by +FROM + schedule s +WHERE + s.id = ?; + +-- 수정 +UPDATE + schedule +SET + date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, + updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +### Store + +**매장 상세 조회** + +```sql +-- 조회 +SELECT + s.id, s.address, s.business_reg_num, s.contact, s.created_at, + s.created_by, s.name, s.region_code, s.status, s.updated_at, + s.updated_by +FROM + store s +WHERE + s.id = ? AND s.status = 'ACTIVE'; + +-- 지역 정보 조회 +SELECT + r.code, r.sido_code, r.sido_name, r.sigungu_code, r.sigungu_name +FROM + region r +WHERE + r.code = ?; + +-- 감사 정보 조회(createdBy, updatedBy) +SELECT + a.id, a.account, a.created_at, a.created_by, a.name, a.password, + a.permission_level, a.phone, a.store_id, a.type, a.updated_at, + a.updated_by +FROM + admin a +WHERE + a.id = ?; +``` + +**매장 등록** + +```sql +-- 이름 중복 확인 +SELECT s.id FROM store s WHERE s.name = ? LIMIT 1; + +-- 연락처 중복 확인 +SELECT s.id FROM store s WHERE s.contact = ? LIMIT 1; + +-- 주소 중복 확인 +SELECT s.id FROM store s WHERE s.address = ? LIMIT 1; + +-- 사업자번호 중복 확인 +SELECT s.id FROM store s WHERE s.business_reg_num = ? LIMIT 1; + +-- 추가 +INSERT INTO store ( + address, business_reg_num, contact, created_at, created_by, + name, region_code, status, updated_at, updated_by, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +**매장 수정** + +```sql +-- 조회 +SELECT + s.id, s.address, s.business_reg_num, s.contact, s.created_at, + s.created_by, s.name, s.region_code, s.status, s.updated_at, + s.updated_by +FROM + store s +WHERE + s.id = ? AND s.status = 'ACTIVE'; + +-- 수정 +UPDATE + store +SET + address = ?, business_reg_num = ?, contact = ?, name = ?, + region_code = ?, status = ?, updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +**비활성화(status = DISABLE)** + +```sql +-- 조회 +SELECT + s.id, s.address, s.business_reg_num, s.contact, s.created_at, + s.created_by, s.name, s.region_code, s.status, s.updated_at, + s.updated_by +FROM + store s +WHERE + s.id = ? AND s.status = 'ACTIVE'; + +-- 수정 +UPDATE + store +SET + address = ?, business_reg_num = ?, contact = ?, name = ?, + region_code = ?, status = ?, updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +**모든 매장 조회** + +```sql +SELECT + s.id, s.address, s.business_reg_num, s.contact, s.created_at, + s.created_by, s.name, s.region_code, s.status, s.updated_at, + s.updated_by +FROM + store s +WHERE + s.status = 'ACTIVE' + AND (? IS NULL OR s.region_code LIKE ?); +``` + +**개별 매장 상세 조회** + +```sql +SELECT + s.id, s.address, s.business_reg_num, s.contact, s.created_at, + s.created_by, s.name, s.region_code, s.status, s.updated_at, + s.updated_by +FROM + store s +WHERE + s.id = ? AND s.status = 'ACTIVE'; +``` + +### Theme + +**생성** + +```sql +-- 이름으로 조회 +SELECT + t.id +FROM + theme t +WHERE + t.name = ? +LIMIT 1; + +-- 추가 +INSERT INTO theme ( + available_minutes, created_at, created_by, description, difficulty, + expected_minutes_from, expected_minutes_to, is_active, max_participants, + min_participants, name, price, thumbnail_url, updated_at, updated_by, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +**Active인 모든 테마 조회** + +```sql +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t +WHERE + t.is_active = TRUE; +``` + +**테마 목록 조회** + +```sql +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t; +``` + +**감사 정보 포함 개별 테마 상세 조회** + +```sql +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t +WHERE + t.id = ?; +``` + +**개별 테마 조회** + +```sql +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t +WHERE + t.id = ?; +``` + +**삭제** + +```sql +-- 조회 +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t +WHERE + t.id = ?; + +-- 삭제 +DELETE FROM theme WHERE id = ?; +``` + +**수정** + +```sql +-- 조회 +SELECT + t.id, t.available_minutes, t.created_at, t.created_by, t.description, + t.difficulty, t.expected_minutes_from, t.expected_minutes_to, + t.is_active, t.max_participants, t.min_participants, t.name, + t.price, t.thumbnail_url, t.updated_at, t.updated_by +FROM + theme t +WHERE + t.id = ?; + +-- 수정 +UPDATE + theme +SET + available_minutes = ?, description = ?, difficulty = ?, + expected_minutes_from = ?, expected_minutes_to = ?, is_active = ?, + max_participants = ?, min_participants = ?, name = ?, price = ?, + thumbnail_url = ?, updated_at = ?, updated_by = ? +WHERE + id = ?; +``` + +**인기 테마 조회** + +```sql +SELECT + t.id, t.name, t.description, t.difficulty, t.thumbnail_url, t.price, + t.min_participants, t.max_participants, + t.available_minutes, t.expected_minutes_from, t.expected_minutes_to +FROM + theme t + JOIN ( + SELECT + s.theme_id, count(*) as reservation_count + FROM + schedule s + JOIN + reservation r ON s.id = r.schedule_id AND r.status = 'CONFIRMED' + WHERE + s.status = 'RESERVED' + AND (s.date BETWEEN :startFrom AND :endAt) + GROUP BY + s.theme_id + ORDER BY + reservation_count desc + LIMIT :count + ) ranked_themes ON t.id = ranked_themes.theme_id +``` + +### User + +**회원가입** + +```sql +-- 이메일 중복 확인 +SELECT + u.id +FROM + users u +WHERE + u.email = ? +LIMIT 1; + +-- 연락처 중복 확인 +SELECT + u.id +FROM + users u +WHERE + u.phone = ? +LIMIT 1; + +-- 추가 +INSERT INTO users ( + created_at, created_by, email, name, password, phone, region_code, + status, updated_at, updated_by, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? +); + +-- 상태 변경 이력 추가 +INSERT INTO user_status_history ( + created_at, created_by, reason, status, updated_at, updated_by, + user_id, id +) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ? +); +``` + +**연락처 정보 조회** + +```sql +SELECT + u.id, u.created_at, u.created_by, u.email, u.name, u.password, + u.phone, u.region_code, u.status, u.updated_at, u.updated_by +FROM + users u +WHERE + u.id = ?; +``` \ No newline at end of file