Skip to main content

πŸš— 157339. μžλ™μ°¨ λŒ€μ—¬ κΈ°λ‘μ—μ„œ μž₯κΈ°/단기 λŒ€μ—¬ κ΅¬λΆ„ν•˜κΈ° (SQL)

1. 문제 μš”μ•½

  • car_rental_company_car, car_rental_company_rental_history, car_rental_company_discount_plan ν…Œμ΄λΈ” 제곡
  • '세단', 'SUV' μ°¨μ’… 쀑 2022λ…„ 11μ›” ν•œ 달 κ°„ λŒ€μ—¬ κ°€λŠ₯ν•œ μ°¨λŸ‰μ„ μ°Ύκ³ , 30일 μš”κΈˆ κΈ°μ€€ μ •λ ¬

2. μ‹€νŒ¨ν•œ μ‹œλ„λ“€

❌ 첫 번째 μ‹œλ„

SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee
FROM (car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j
     INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01'
ORDER BY fee DESC, j.car_type, j.car_id DESC
  • 였λ₯˜: 'SUV' λŠ” 항상 true둜 인식됨 β†’ λͺ¨λ“  car_type 포함됨
  • λ‚ μ§œ 쑰건 λΆ€μ •ν™•

❌ 두 번째 μ‹œλ„

FROM (SELECT * FROM ... ) AS j ...
  • ꡬ쑰만 바꿨을 뿐 논리적 였λ₯˜ 동일

❌ μ„Έ 번째 μ‹œλ„

FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate FROM ... ) AS j ...
  • 계산은 λ§žμ•˜μ§€λ§Œ μ‹€μˆ˜κ°’ 좜λ ₯ β†’ ROUND() ν•„μš”
  • car_id 쀑볡 β†’ GROUP BY ν•„μš”

❌ λ„€ 번째 μ‹œλ„

... GROUP BY car_id ...
  • WHERE절 였λ₯˜ 계속됨 (car_type = '세단' OR 'SUV' 문제)

❌ λ‹€μ„― 번째 μ‹œλ„

WHERE car_type IN ('세단', 'SUV') AND h.end_date < '2024-11-01'
  • WHERE 절 였λ₯˜ μˆ˜μ • 성곡
  • ν•˜μ§€λ§Œ 핡심 쑰건 빠짐 β†’ 11μ›” ν•œ 달 "λŒ€μ—¬ λΆˆκ°€ν•œ μ°¨λŸ‰"을 μ œμ™Έν•΄μ•Ό 함

❌ μ—¬μ„― 번째 μ‹œλ„

... AND d.duration_type = '30일 이상'
... AND h.start_date <= '2022-11-01' AND h.end_date >= '2022-11-30'
  • λŒ€μ—¬μ€‘μΈ μ°¨λŸ‰λ§Œ ν¬ν•¨λ˜λŠ” 였λ₯˜ β†’ μ œμ™Έ 쑰건이 μ•„λ‹Œ 포함 쑰건이 됨

❌ 일곱 번째 μ‹œλ„

WHERE car_type IN (...) AND (SELECT car_id FROM ...)
  • WHERE μ ˆμ— μ„œλΈŒμΏΌλ¦¬ 단독 μ‚¬μš© β†’ 닀쀑행 였λ₯˜ λ°œμƒ

❌ μ—¬λŸ 번째 μ‹œλ„

WHERE car_type IN (...) AND NOT EXISTS (SELECT ...)
  • μ²˜μŒμ—” 쑰건 λΆˆμ™„μ „ν–ˆμŒ (j.car_id 연동 μ•ˆλ¨)

βœ… 아홉 번째 μ‹œλ„ (성곡)

SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (
    SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate
    FROM car_rental_company_car c
    INNER JOIN car_rental_company_discount_plan d
    ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j
WHERE car_type IN ('세단', 'SUV')
AND NOT EXISTS (
    SELECT 1
    FROM car_rental_company_rental_history h2
    WHERE h2.car_id = j.car_id
    AND NOT (h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30')
)
ORDER BY fee DESC, j.car_type, j.car_id DESC;
  • NOT EXISTS μ ˆμ—μ„œ "11μ›” ν•œ 달이라도 λŒ€μ—¬λœ μ°¨λŠ” μ œμ™Έ"
  • λ‚ μ§œ λ²”μœ„: NOT (end < 11μ›” 1일 OR start > 11μ›” 30일) β†’ κ²ΉμΉ˜λŠ” λŒ€μ—¬κΈ°κ°„ 필터링
  • 할인 쑰건: duration_type = '30일 이상'
  • μš”κΈˆ: ROUND() ν•¨μˆ˜λ‘œ μ •μˆ˜ 처리

3. κ΅ν›ˆ 및 포인트 정리

3.1 SQL WHERE μ ˆμ—μ„œ 논리 였λ₯˜ 주의

  • 'SUV' 단독은 항상 true β†’ IN ('세단', 'SUV') μ‚¬μš©ν•΄μ•Ό μ •ν™•

3.2 λ‚ μ§œ λ²”μœ„ 필터링 μ‹œ NOT EXISTS μ‚¬μš© 팁

  • κ²ΉμΉ˜λŠ” λ‚ μ§œ 쑰건을 λΆ€μ •ν•΄μ„œ μ œμ™Έν•  μ°¨λŸ‰μ„ μ •μ˜ν•΄μ•Ό 함
  • κΈ°κ°„ κ²ΉμΉ¨ 확인은 NOT (end < μ‹œμž‘ OR start > μ’…λ£Œ)둜 λΆ€μ •

3.3 GROUP BYλŠ” 쀑볡 λ°©μ§€μš© μ•„λ‹˜

  • λ¬Έμ œμ—μ„œ μš”κ΅¬ν•˜μ§€ μ•ŠλŠ” 이상, JOIN κ²°κ³Ό 쀑볡 λ°œμƒ 원인을 λ¨Όμ € 점검할 것

3.4 ROUND ν•¨μˆ˜λ‘œ μ‹€μˆ˜ 처리

  • 계산식 κ²°κ³ΌλŠ” μ‹€μˆ˜ β†’ ROUND()둜 μ •μˆ˜ λ³€ν™˜ ν•„μš”

πŸ“Œ TMI:

  • λ³΅μž‘ν•œ SQL일수둝 μ μ§„μ μœΌλ‘œ ν…ŒμŠ€νŠΈν•˜λ©΄μ„œ WHERE절 쑰건을 λͺ…ν™•νžˆ νŒŒμ•…ν•΄μ•Ό 함.