2017-05-24 1 views
0

Je travaille sur un système de location de voiture utilisant Codeigniter où un véhicule peut avoir plusieurs plages de dates indisponibles. J'ai créé un tableau séparé pour les plages de dates non disponibles, maintenant je veux que l'utilisateur entre une plage de dates et sélectionne toutes les voitures qui ne chevauchent pas les plages de dates non disponibles de ces voitures. Voici mon code.MySQL vérifie si la plage de dates chevauche d'autres plages de dates?

$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'); 

Raw Interrogation

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

double possible de [Vérifier chevauchement des plages de dates dans MySQL] (https://stackoverflow.com/questions/2545947/check-overlap-of-date-ranges-in-mysql) – JazZ

Répondre

0

L'algorithme de base pour une plage de dates qui ne se chevauchent pas est:

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

Alors traduit à votre requête, il devrait être quelque chose comme:

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

Son seul travail si il y a une seule plage indisponible dans le tableau alors que dans mon cas il peut y avoir plusieurs plages de dates indisponibles pour chaque véhicule. – BTree

+0

Qu'obtenez-vous s'il y a plusieurs plages non disponibles? – silkfire

+0

Il sélectionne les voitures même les chevauchements de gamme s'il y a plusieurs gammes non disponibles pour le même véhicule !!! – BTree

0

Et finalement la requête suivante a fonctionné pour moi.

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`