2017-05-24 12 views
0

私はCodeigniterを使用してレンタカーシステムに取り組んでいますが、車両には複数の使用不可能な日付範囲がある場合があります。利用できない日付範囲のための別のテーブルを作成しました。ユーザーは日付範囲を入力し、その自動車の利用不可能な日付範囲と重複しないすべての車を選択します。以下は私のコードです。MySQLは、日付範囲が他の日付範囲と重複していないかどうかを確認しますか?

$d1 = date('Y-m-d', strtotime($pickup)); 
    $d2 = date('Y-m-d', strtotime($dropoff)); 
// $this->db->where($d1." NOT BETWEEN date_ranges.start_date AND date_ranges.end_date AND " . $d2.' NOT BETWEEN date_ranges.start_date AND date_ranges.end_date'); 
    $this->db->where("'$d1' NOT BETWEEN date_ranges.start_date AND date_ranges.end_date AND '$d2' NOT BETWEEN date_ranges.start_date AND date_ranges.end_date OR ('$d1' < date_ranges.start_date AND '$d2' > date_ranges.end_date) "); 
// $this->db->where(" '$d1' <= date_ranges.end_date AND date_ranges.start_date <= '$d2'"); 

    $query = ->join('date_ranges', 'vehicles.id = date_ranges.vehicle_id', 'left') 
    ->group_by('vehicles.id') 
    ->get('vehicles'); 

生のクエリ

SELECT `vehicles`.`id`, `vehicles`.`year-`, `vehicles`.`model`, 
`vehicles`.`nightly_rate`, `vehicles`.`class`, 
`vehicle_pictures`.`picture`, 
`vehicles`.`people` FROM `vehicles` LEFT JOIN `vehicle_pictures` ON 
    `vehicles`.`id` = `vehicle_pictures`.`vehicle_id` LEFT JOIN `date_ranges` 
    ON 
    `vehicles`.`id` = `date_ranges`.`vehicle_id` 
    WHERE (`country` LIKE '%%' 
    ESCAPE 
    '!' OR `state` LIKE '%%' ESCAPE '!' OR `city` LIKE '%%' ESCAPE '!' OR 
    `street` 
    LIKE '%%' ESCAPE '!' OR `zip` LIKE '%%' ESCAPE '!') 
    AND '2017-05-23' 
    NOT 
    BETWEEN `date_ranges`.`start_date` AND date_ranges.end_date AND '2017- 
    05-24' 
    NOT 
    BETWEEN `date_ranges`.`start_date` AND date_ranges.end_date OR ('2017- 
    05-23' < 
    `date_ranges`.`start_date` AND '2017-05-24' > date_ranges.end_date) AND 
    `vehicles`.`people` > '1' GROUP BY `vehicles`.`id`; 
+2

(https://stackoverflow.com/questions/2545947/check-overlap-of-date-ranges-in-mysql)[MySQLで日付範囲の重複をチェック] – JazZ

答えて

0

重複しない日付範囲のための基本的なアルゴリズムです。だからあなたのクエリに変換

NOT(unavailable_date_range_START <= desired_date_range_END) AND NOT(unavailable_date_range_END >= desired_date_range_START) 

、それはのようなものでなければなりません。

SELECT `vehicles`.`id`, `vehicles`.`year`, `vehicles`.`model`, `vehicles`.`nightly_rate`, 
     `vehicles`.`class`, `vehicle_pictures`.`picture`, `vehicles`.`people` 

FROM `vehicles` 

LEFT JOIN `vehicle_pictures` ON (`vehicles`.`id` = `vehicle_pictures`.`vehicle_id`) 

WHERE ( `country` LIKE '%%' ESCAPE '!' 
     OR `state` LIKE '%%' ESCAPE '!' 
     OR `city` LIKE '%%' ESCAPE '!' 
     OR `street` LIKE '%%' ESCAPE '!' 
     OR `zip`  LIKE '%%' ESCAPE '!') 
AND `vehicles`.`id` NOT IN(SELECT DISTINCT `date_ranges`.`vehicle_id` 

          FROM `date_ranges` 

          WHERE `date_ranges`.`start_date` <= '$d2' AND `date_ranges`.`end_date` >= '$d1') 
+0

そのだけ作業の可能性のある重複した場合私の場合、各車両に複数の利用不可能な日付範囲が存在する可能性がありますが、テーブルには利用できない範囲が1つあります。 – BTree

+0

複数の利用できない範囲がある場合はどうなりますか? – silkfire

+0

同じ車両の複数の利用不可能な範囲がある場合、それは範囲オーバーラップでも車を選択する!!! – BTree

0

最後に次のクエリが私のために働いた。

SELECT `vehilces`.`id`, `vehilces`.`year`, `vehilces`.`model`, 
`vehilces`.`nightly_rate`, `vehilces`.`class`, `vehilce_pictures`.`picture`, 
`vehilces`.`people`, `date_ranges`.`start_date`, `date_ranges`.`end_date` FROM 
`vehilces` LEFT JOIN `date_ranges` ON `vehilces`.`id` = 
`date_ranges`.`vehilce_id` LEFT JOIN `vehilce_pictures` ON `vehilces`.`id` = 
`vehilce_pictures`.`vehilce_id` WHERE (`country` LIKE '%%' ESCAPE '!' OR 
`state` LIKE '%%' ESCAPE '!' OR `city` LIKE '%%' ESCAPE '!' OR `street` LIKE 
'%%' ESCAPE '!' OR `zip` LIKE '%%' ESCAPE '!') AND vehilces.id NOT IN(SELECT 
DISTINCT vehilce_id from date_ranges WHERE ('$d1' <= end_date) and ('$d2' >= 
start_date) or ('$d1' <= end_date) and (start_date <= '$d2')) AND 
`vehilces`.`people` > '1' GROUP BY `vehilces`.`id` 
関連する問題