前提・実現したいこと
社内システムなのですが、空きのある社用車の一覧を取得する部分をLaravelで実装しています。
全ては見せられませんが、一部ERDの抜粋です。
空きのある社用車の一覧を取得する部分の条件を考えているのですが、やりたいことは日本語にすることはできるのですが、条件を反転すると
2020-04-04 13:00迄、かつ、2020-04-04 18:00以降の車の一覧を取得するSQLになってしまいうまくSQLが組み立てられません。
同じような機能を実装された方がいらっしゃいましたらアドバイスいただきたいです。
該当のソースコード
/** * @param array $relations * * @return Car[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection */ public function getXxx(array $relations = []) { /** * DB設計的に、車(Car)は複数の予約(Reservations)を持っている。 * 2020-04-04 13:00 ~ 2020-04-04 18:00の空きのある車の一覧を取得する条件を考える! */ $cars = Car::with(['reservations']) ->where('is_abolition', false) ->whereHas('reservations', function(\Illuminate\Database\Eloquent\Builder $query) { $query->where('start_datetime', '>', '2020-04-04 13:00'); $query->where('end_datetime', '<', '2020-04-04 18:00'); }) ->orderBy('display_priority') ->get(); dd($cars); return $cars; }
ちなみに予約できる時間は08:00~20:00までです。
試したこと
3日ほどSQL条件考えたり、似たような機能の記事がないか調べたりしていますが、記事もなかなか見つからず困っています。
とりあえず、普通に考えると以下になると思います。
・CarsテーブルとReservationsテーブルをFULL (OUTER) JOIN (完全外部結合)する
・Reservationsテーブルの2020-04-04 13:00 ~ 2020-04-04 18:00なレコードを除外する。
・余ったレコードをCars.idでgroup化する
・これらが空きのある車
レンタカーのような実装は初めてなので
このロジックが適切なのか、そもそもテーブル設計がこれで良いのかという疑問もあります。
このロジックが適切だったとしても、レコードを除外するという部分が自分の中では曲者で、取得とは逆のことをするので...
他にも
ユーザーが同じタイミングで予約してしまった時はサーバー側ではどういう処理をするのが適切なのか
ユーザーが同じタイミングで予約できないようにする(Reservationsテーブルにstatusカラムを持たせておいて、日時入力後の検索結果から該当の車をクリックしたタイミングでstatusを仮としたレコードを追加しておく?)案など
アドバイスいただけると助かります。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
意図した結果にはなりましたが、なぜこうなるのかが頭で理解できていない。人に日本語で説明ができない。。。
回答1件
あなたの回答
tips
プレビュー