IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Afficher les plages horaires libres de 6 heures entre 06:30 et minuit de réservation


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut Afficher les plages horaires libres de 6 heures entre 06:30 et minuit de réservation
    Bonjour,

    Je planche depuis quelques jours sur la réalisation d'une requête qui me permettrait d'afficher les plages horaires libres de 6 heures entre 06:30 et minuit.

    J'arrive a afficher les plages horaires occupées, mais étant un novice dans la création de requêtes MYSQL, ce problème dépasse mes compétences actuelles.

    Ma table des réservations contient entre autres deux champs (vous trouverez un dump annexé en bas de page) :

    id = réservation|entraînement ou événement interne
    book_crewstartdate = date|heure d'embarquement de l'équipage
    book_crewenddate = date|heure de débarquement de l'équipage

    Cette table contient également en plus des réservations, des sessions d'entraînement et des événements internes, je n'ai pas besoin de les différenciers, la requête doit porter sur toutes les plages horaires d'ores et déjà occupées.

    Je vous donne un exemple:

    Dans ma base de données j'ai deux plages horaires réservées par des entraînements le 31 08 2017 :

    de 07:30 à 09:30
    et de 13:30 à 15:30

    J'ai donc 6 plages horaires de 6 heures possibles que la requête devrait pouvoir me retourner :

    de 15:30 à 21:30
    de 16:00 à 22:00
    de 16:30 à 22:30
    de 17:00 à 23:00
    de 17:30 à 23:30
    et de 18:00 à 00:00 (minuit)

    comme vous pouvez le voir sur le graphique annexé en bas de page.

    Je suis bloqué sur ce problème et je vous remercie d'avance de votre expertise pour m'aider à le résoudre.

    Marc

    DUMP de ma table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    -- phpMyAdmin SQL Dump
    -- version 4.2.12deb2+deb8u1
    -- http://www.phpmyadmin.net
    --
    -- Client :  localhost
    -- Généré le :  Ven 02 Septembre 2016 à 08:16
    -- Version du serveur :  10.0.26-MariaDB-1~jessie
    -- Version de PHP :  5.6.23-0+deb8u1
     
    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    SET time_zone = "+00:00";
     
    --
    -- Base de données : 
    --
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `fab_booking`
    --
     
    CREATE TABLE IF NOT EXISTS `fab_booking` (
    `id` int(11) NOT NULL,
      `book_event_id` smallint(1) DEFAULT NULL,
      `datetme` datetime DEFAULT NULL,
      `book_company` varchar(255) DEFAULT NULL,
      `book_bookingdate` datetime DEFAULT NULL,
      `book_starttime` smallint(5) unsigned DEFAULT NULL,
      `book_termrental` smallint(5) unsigned DEFAULT NULL,
      `book_landingtime` text,
      `book_bookingstartdate` datetime DEFAULT NULL,
      `book_bookingenddate` datetime DEFAULT NULL,
      `book_crewstartdate` datetime DEFAULT NULL,
      `book_crewenddate` datetime DEFAULT NULL,
      `date_time` datetime DEFAULT NULL
    ) ENGINE=MyISAM AUTO_INCREMENT=78 DEFAULT CHARSET=utf8;
     
    --
    -- Contenu de la table `fab_booking`
    --
     
    INSERT INTO `fab_booking` (`id`, `book_event_id`, `datetme`, `book_company`, `book_bookingdate`, `book_starttime`, `book_termrental`, `book_landingtime`, `book_bookingstartdate`, `book_bookingenddate`, `book_crewstartdate`, `book_crewenddate`, `date_time`) VALUES
    (35, 1, '2016-04-23 00:00:00', 'Entreprise 1', '2016-04-26 00:00:00', 1, 1, '11:00', '2016-04-26 08:00:00', '2016-04-26 11:00:00', '2016-04-26 07:30:00', '2016-04-26 13:30:00', NULL),
    (36, 1, '2016-05-18 00:00:00', 'Entreprise 2', '2016-05-25 00:00:00', 1, 3, '13:00', '2016-05-25 08:00:00', '2016-05-25 13:00:00', '2016-05-25 07:30:00', '2016-05-25 13:30:00', NULL),
    (37, 1, '2016-05-25 00:00:00', 'Entreprise 3', '2016-06-26 00:00:00', 2, 5, '15:00', '2016-06-26 08:00:00', '2016-06-26 15:00:00', '2016-06-26 07:30:00', '2016-06-26 15:30:00', NULL),
    (38, 1, '2016-05-18 00:00:00', 'Entreprise 4', '2016-09-01 00:00:00', 3, 5, '15:30', '2016-09-01 08:30:00', '2016-09-01 15:30:00', '2016-09-01 07:00:00', '2016-09-01 17:00:00', NULL),
    (44, 1, '2016-05-18 00:00:00', 'Entreprise 5', '2016-09-02 00:00:00', 2, 5, '15:00', '2016-09-02 08:00:00', '2016-09-02 15:00:00', '2016-09-02 06:30:00', '2016-09-02 16:30:00', NULL),
    (45, 1, '2016-05-28 00:00:00', 'Entreprise 6', '2016-09-03 00:00:00', 2, 1, '11:00', '2016-09-03 08:00:00', '2016-09-03 11:00:00', '2016-09-03 06:30:00', '2016-09-03 12:30:00', NULL),
    (46, 1, '2016-05-27 00:00:00', 'Entreprise 7', '2016-09-04 00:00:00', 1, 3, '13:00', '2016-09-04 08:00:00', '2016-09-04 13:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL),
    (47, 1, '2016-06-02 00:00:00', 'Entreprise 8', '2016-09-05 13:11:06', 2, 1, '11:00', '2016-09-05 08:00:00', '2016-09-05 11:00:00', '2016-09-05 06:30:00', '2016-09-05 12:30:00', NULL),
    (50, 2, '2016-06-11 00:00:00', 'Training session', '2016-08-01 08:30:00', 3, 3, '11:30', '2016-08-01 08:30:00', '2016-08-01 11:30:00', '2016-08-01 08:00:00', '2016-08-01 12:00:00', NULL),
    (53, 1, '2016-07-13 00:00:00', 'Entreprise 9', '2016-09-06 17:23:10', 3, 1, '11:30', '2016-09-06 08:30:00', '2016-09-06 11:30:00', '2016-09-06 07:00:00', '2016-09-06 13:00:00', NULL),
    (55, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-04 00:00:00', 3, 2, '11:00', '2016-08-04 09:00:00', '2016-08-04 11:00:00', '2016-08-04 08:30:00', '2016-08-04 11:30:00', NULL),
    (56, 1, '2016-07-02 00:00:00', 'Entreprise 10', '2016-09-07 17:09:16', 1, 1, '11:00', '2016-09-07 08:00:00', '2016-09-07 11:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL),
    (57, 1, '2016-07-02 00:00:00', 'Entreprise 11', '2016-09-08 17:12:52', 2, 1, '11:30', '2016-09-08 08:30:00', '2016-09-08 11:30:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL),
    (59, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-07 00:00:00', 3, 1, '10:00', '2016-08-07 09:00:00', '2016-08-07 10:00:00', '2016-08-07 08:30:00', '2016-08-07 10:30:00', NULL),
    (61, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-10 18:00:00', 41, 1, '19:00', '2016-08-10 18:00:00', '2016-08-10 19:00:00', '2016-08-10 17:30:00', '2016-08-10 19:30:00', NULL),
    (62, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-12 00:00:00', 3, 1, '10:00', '2016-08-12 09:00:00', '2016-08-12 10:00:00', '2016-08-12 08:30:00', '2016-08-12 11:30:00', NULL),
    (63, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-15 14:30:00', 27, 1, '15:30', '2016-08-15 14:30:00', '2016-08-15 15:30:00', '2016-08-15 14:00:00', '2016-08-15 16:00:00', NULL),
    (64, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-18 00:00:00', 3, 1, '10:00', '2016-08-18 09:00:00', '2016-08-18 10:00:00', '2016-08-18 08:30:00', '2016-08-18 10:30:00', NULL),
    (65, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-22 20:00:00', 49, 1, '21:00', '2016-08-22 20:00:00', '2016-08-22 21:00:00', '2016-08-22 19:30:00', '2016-08-22 21:30:00', NULL),
    (66, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-31 14:00:00', 25, 1, '15:00', '2016-08-31 14:00:00', '2016-08-31 15:00:00', '2016-08-31 13:30:00', '2016-08-31 15:30:00', NULL),
    (68, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-30 00:00:00', 3, 1, '10:00', '2016-08-30 09:00:00', '2016-08-30 10:00:00', '2016-08-30 08:30:00', '2016-08-30 10:30:00', NULL),
    (69, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-04 15:30:00', 31, 1, '16:30', '2016-08-04 15:30:00', '2016-08-04 16:30:00', '2016-08-04 15:00:00', '2016-08-04 17:00:00', NULL),
    (70, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-31 00:00:00', 1, 1, '09:00', '2016-08-31 08:00:00', '2016-08-31 09:00:00', '2016-08-31 08:30:00', '2016-08-31 09:30:00', NULL),
    (71, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-29 08:00:00', 1, 1, '09:00', '2016-08-29 08:00:00', '2016-08-29 09:00:00', '2016-08-29 07:30:00', '2016-08-29 09:30:00', NULL),
    (72, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-22 09:00:00', 5, 1, '10:00', '2016-08-22 09:00:00', '2016-08-22 10:00:00', '2016-08-22 08:30:00', '2016-08-22 10:30:00', NULL),
    (73, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-23 00:00:00', 11, 1, '14:00', '2016-08-23 13:00:00', '2016-08-23 14:00:00', '2016-08-23 12:30:00', '2016-08-23 13:30:00', NULL),
    (74, 3, '0000-00-00 00:00:00', 'Internation event', '2016-08-22 00:00:00', 7, 1, '12:00', '2016-08-22 11:00:00', '2016-08-22 12:00:00', '2016-08-22 10:30:00', '2016-08-22 11:30:00', NULL),
    (75, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-23 08:00:00', 1, 2, '10:00', '2016-08-23 08:00:00', '2016-08-23 10:00:00', '2016-08-23 07:30:00', '2016-08-23 10:30:00', NULL),
    (76, 1, '2016-08-24 00:00:00', 'Entreprise 12', '2016-10-31 00:00:00', 2, 1, '11:00', '2016-10-31 08:00:00', '2016-10-31 11:00:00', '2016-10-31 06:30:00', '2016-10-31 12:30:00', NULL),
    (77, 2, '0000-00-00 00:00:00', 'Training session', '2016-08-26 14:00:00', 25, 3, '17:00', '2016-08-26 14:00:00', '2016-08-26 17:00:00', '2016-08-26 13:30:00', '2016-08-26 17:30:00', NULL);
     
    --
    -- Index pour les tables exportées
    --
     
    --
    -- Index pour la table `fab_booking`
    --
    ALTER TABLE `fab_booking`
     ADD PRIMARY KEY (`id`), ADD KEY `fb_prefilter_book_event_id_INDEX` (`book_event_id`);
     
    --
    -- AUTO_INCREMENT pour les tables exportées
    --
     
    --
    -- AUTO_INCREMENT pour la table `fab_booking`
    --
    ALTER TABLE `fab_booking`
    MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=78;
    Images attachées Images attachées  

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut marc-q.

    Citation Envoyé par marc-q
    une requête qui me permettrait d'afficher les plages horaires libres de 6 heures entre 06:30 et minuit.
    Donc une amplitude de six heures au maximum commençant à 6:30 et se terminant à 24:00.

    Il suffit de donner tous les intervalles que tu désires obtenir :
    --> de 06:30 à 12:30
    --> de 07:00 à 13:00
    --> de 07:30 à 13:30
    --> de 08:00 à 14:00
    --> de 08:30 à 14:30
    --> de 09:00 à 15:00
    --> de 09:30 à 15:30
    --> de 10:00 à 16:00
    --> de 10:30 à 16:30
    --> de 11:00 à 17:00
    --> de 11:30 à 17:30
    --> de 12:00 à 18:00
    --> de 12:30 à 18:30
    --> de 13:00 à 19:00
    --> de 13:30 à 19:30
    --> de 14:00 à 20:00
    --> de 14:30 à 20:30
    --> de 15:00 à 21:00
    --> de 15:30 à 21:30
    --> de 16:00 à 22:00
    --> de 16:30 à 22:30
    --> de 17:00 à 23:00
    --> de 17:30 à 23:30
    --> de 18:00 à 24:00

    Citation Envoyé par marc-q
    Dans ma base de données j'ai deux plages horaires réservées par des entraînements le 31 08 2017 :
    de 07:30 à 09:30
    et de 13:30 à 15:30
    Tu veux récupérer toutes les plages horaires où le recouvrement ne se fait pas.

    Voici un exemple que tu peux utiliser pour appliquer à ton problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    drop table if exists `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`        integer unsigned  NOT NULL AUTO_INCREMENT,
      `time_deb`  time              NOT NULL,
      `time_fin`  time              NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`time_deb`,`time_fin`) values
      ('06:30:00','12:30:00'),('07:00:00','13:00:00'),('07:30:00','13:30:00'),('08:00:00','14:00:00'),('08:30:00','14:30:00'),('09:00:00','15:00:00'),
      ('09:30:00','15:30:00'),('10:00:00','16:00:00'),('10:30:00','16:30:00'),('11:00:00','17:00:00'),('11:30:00','17:30:00'),('12:00:00','18:00:00'),
      ('12:30:00','18:30:00'),('13:00:00','19:00:00'),('13:30:00','19:30:00'),('14:00:00','20:00:00'),('14:30:00','20:30:00'),('15:00:00','21:00:00'),
      ('15:30:00','21:30:00'),('16:00:00','22:00:00'),('16:30:00','22:30:00'),('17:00:00','23:00:00'),('17:30:00','23:30:00'),('18:00:00','24:00:00')
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+----------+----------+
    | id | time_deb | time_fin |
    +----+----------+----------+
    |  1 | 06:30:00 | 12:30:00 |
    |  2 | 07:00:00 | 13:00:00 |
    |  3 | 07:30:00 | 13:30:00 |
    |  4 | 08:00:00 | 14:00:00 |
    |  5 | 08:30:00 | 14:30:00 |
    |  6 | 09:00:00 | 15:00:00 |
    |  7 | 09:30:00 | 15:30:00 |
    |  8 | 10:00:00 | 16:00:00 |
    |  9 | 10:30:00 | 16:30:00 |
    | 10 | 11:00:00 | 17:00:00 |
    | 11 | 11:30:00 | 17:30:00 |
    | 12 | 12:00:00 | 18:00:00 |
    | 13 | 12:30:00 | 18:30:00 |
    | 14 | 13:00:00 | 19:00:00 |
    | 15 | 13:30:00 | 19:30:00 |
    | 16 | 14:00:00 | 20:00:00 |
    | 17 | 14:30:00 | 20:30:00 |
    | 18 | 15:00:00 | 21:00:00 |
    | 19 | 15:30:00 | 21:30:00 |
    | 20 | 16:00:00 | 22:00:00 |
    | 21 | 16:30:00 | 22:30:00 |
    | 22 | 17:00:00 | 23:00:00 |
    | 23 | 17:30:00 | 23:30:00 |
    | 24 | 18:00:00 | 24:00:00 |
    +----+----------+----------+
    --------------
    set @peri_deb = '07:30:00'
    --------------
     
    --------------
    set @peri_fin = '09:30:00'
    --------------
     
    --------------
    select * from test where not ((time_deb < @peri_fin and time_fin > @peri_deb))
    --------------
     
    +----+----------+----------+
    | id | time_deb | time_fin |
    +----+----------+----------+
    |  7 | 09:30:00 | 15:30:00 |
    |  8 | 10:00:00 | 16:00:00 |
    |  9 | 10:30:00 | 16:30:00 |
    | 10 | 11:00:00 | 17:00:00 |
    | 11 | 11:30:00 | 17:30:00 |
    | 12 | 12:00:00 | 18:00:00 |
    | 13 | 12:30:00 | 18:30:00 |
    | 14 | 13:00:00 | 19:00:00 |
    | 15 | 13:30:00 | 19:30:00 |
    | 16 | 14:00:00 | 20:00:00 |
    | 17 | 14:30:00 | 20:30:00 |
    | 18 | 15:00:00 | 21:00:00 |
    | 19 | 15:30:00 | 21:30:00 |
    | 20 | 16:00:00 | 22:00:00 |
    | 21 | 16:30:00 | 22:30:00 |
    | 22 | 17:00:00 | 23:00:00 |
    | 23 | 17:30:00 | 23:30:00 |
    | 24 | 18:00:00 | 24:00:00 |
    +----+----------+----------+
    --------------
    set @peri_deb = '13:30:00'
    --------------
     
    --------------
    set @peri_fin = '15:30:00'
    --------------
     
    --------------
    select * from test where not ((time_deb < @peri_fin and time_fin > @peri_deb))
    --------------
     
    +----+----------+----------+
    | id | time_deb | time_fin |
    +----+----------+----------+
    |  1 | 06:30:00 | 12:30:00 |
    |  2 | 07:00:00 | 13:00:00 |
    |  3 | 07:30:00 | 13:30:00 |
    | 19 | 15:30:00 | 21:30:00 |
    | 20 | 16:00:00 | 22:00:00 |
    | 21 | 16:30:00 | 22:30:00 |
    | 22 | 17:00:00 | 23:00:00 |
    | 23 | 17:30:00 | 23:30:00 |
    | 24 | 18:00:00 | 24:00:00 |
    +----+----------+----------+
    --------------
    set @peri_deb_1 = '07:30:00'
    --------------
     
    --------------
    set @peri_fin_1 = '09:30:00'
    --------------
     
    --------------
    set @peri_deb_2 = '13:30:00'
    --------------
     
    --------------
    set @peri_fin_2 = '15:30:00'
    --------------
     
    --------------
    select * from test where not ((time_deb < @peri_fin_1 and time_fin > @peri_deb_1))
                       and   not ((time_deb < @peri_fin_2 and time_fin > @peri_deb_2))
    --------------
     
    +----+----------+----------+
    | id | time_deb | time_fin |
    +----+----------+----------+
    | 19 | 15:30:00 | 21:30:00 |
    | 20 | 16:00:00 | 22:00:00 |
    | 21 | 16:30:00 | 22:30:00 |
    | 22 | 17:00:00 | 23:00:00 |
    | 23 | 17:30:00 | 23:30:00 |
    | 24 | 18:00:00 | 24:00:00 |
    +----+----------+----------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus24,

    Merci pour ton retour et d'avoir pris le temps de rédiger ta réponse.

    Je comprends bien ta logique, mais par contre j'ai du mal à l'implémenter, car j'ai encore peu d'expérience.

    Quelques explications sur le contexte :

    Je développe une application sur la base du CMS Joomla et j'utilise un framework, Fabrik, qui permet de créer des applications plus ou moins complexes.

    J'ai besoin de cette requête pour activer ou désactiver les dates dans un champ datepicker selon si elles disposent d'au moins une plage horaire de six heures.

    Si au moins une plage horaire de 6 heures existe, alors la date peut être choisie (cliquée) par contre si aucun plage horaire existe, alors la date ne peut pas être cliquée.

    J'arrive à le faire avec la règle suivante :

    Si au moins une réservation existe alors la date est activée, sinon elle est désactivé.

    Le framework me permet d'injecter du PHP (et naturellement des requêtes) dans les paramètres du champ en question.

    Mon code pour appliquer la règle suivante est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    $myDb = JFactory::getDbo();
    $myQuery = $myDb->getQuery(true);
    $myQuery
        ->select ('DATE(book_bookingstartdate)')
        ->from('fab_booking');
     
    $myDb->setQuery($myQuery);
    $bookedDates = $myDb->loadColumn();
     
    $begin = new DateTime();
    $end = new DateTime('2026-12-31');
     
    $interval = DateInterval::createFromDateString('1 day');
    $period = new DatePeriod($begin, $interval, $end);
     
    $myAllowedDates = array();
     
    foreach( $period as $dt ) {
        $thisDate = $dt->format("Y-m-d");
        if (!in_array($thisDate, $bookedDates)) {
        $myAllowedDates[] = $thisDate;
        }
    }
    return $myAllowedDates;
    Seuls les dates pour lesquelles il n'existe aucune réservation|entraînement|événement interne sont bien activées.

    Il faudrait que je puisse intégrer d'une manière ou d'une autre le "fruit" de ta réflexion, de ton process dans une requête PDO.

    Aurais-tu une idée de la manière dont cela pourrait être réalisé ?

    Merci d'avance de ton retour.

    Marc

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut marc-q.

    Citation Envoyé par marc-q
    par contre j'ai du mal à l'implémenter, car j'ai encore peu d'expérience.
    Tu as certainment dû comprendre que la requête qui t'intéresse est la dernière de mon exemple.
    Et c'est la requête suivante que tu dois implémenter dans ton code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select * from test where not ((time_deb < @peri_fin_1 and time_fin > @peri_deb_1))
                       and   not ((time_deb < @peri_fin_2 and time_fin > @peri_deb_2));
    Pour ce faire, tu as besoin des intervalles (ou période) de temps.
    Mais il y en a de deux sortes :
    --> celle à extraire ( time_deb ; time_fin)
    --> celle servant de comparaison (@peri_deb ; @peri_fin)

    J'ai, bien sûr, simplifier la requête sans tenir compte de tes contraintes fonctionnelles.
    Citation Envoyé par marc-q
    Dans ma base de données j'ai deux plages horaires réservées par des entraînements le 31 08 2017 :

    de 07:30 à 09:30
    et de 13:30 à 15:30
    Ceci correspond à quelles colonnes dans ta table "fab_booking". Je suppose au couple (book_crewstartdate ; book_crewenddate).
    Donc ce que je nomme (@peri_deb ; @peri_fin), c'est en fait (book_crewstartdate ; book_crewenddate).

    Par contre, pour l'autre intervalle de temps ( time_deb ; time_fin), que tu concrétises par la première colonne dans ta dernière image (celle où il y 06:30, 07:00 ... 23:30, 00:00), je ne sais pas d'où tu sors ces heures.
    Dans mon exemple, ceci correspond à ma table "test".
    Je ne peux pas inventer ces plages horaires, si je ne les connais pas à l'avance.

    Voici le même exemple, mais avec deux tables.
    La première table "test" reste la même, c'est-à-dire les plages horaires.
    La seconde table "periode" correspond à ta table "fab_booking".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    drop table if exists `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`        integer unsigned  NOT NULL AUTO_INCREMENT Primary Key,
      `time_deb`  time              NOT NULL,
      `time_fin`  time              NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`time_deb`,`time_fin`) values
      ('06:30:00','12:30:00'),('07:00:00','13:00:00'),('07:30:00','13:30:00'),('08:00:00','14:00:00'),('08:30:00','14:30:00'),('09:00:00','15:00:00'),
      ('09:30:00','15:30:00'),('10:00:00','16:00:00'),('10:30:00','16:30:00'),('11:00:00','17:00:00'),('11:30:00','17:30:00'),('12:00:00','18:00:00'),
      ('12:30:00','18:30:00'),('13:00:00','19:00:00'),('13:30:00','19:30:00'),('14:00:00','20:00:00'),('14:30:00','20:30:00'),('15:00:00','21:00:00'),
      ('15:30:00','21:30:00'),('16:00:00','22:00:00'),('16:30:00','22:30:00'),('17:00:00','23:00:00'),('17:30:00','23:30:00'),('18:00:00','24:00:00')
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+----------+----------+
    | id | time_deb | time_fin |
    +----+----------+----------+
    |  1 | 06:30:00 | 12:30:00 |
    |  2 | 07:00:00 | 13:00:00 |
    |  3 | 07:30:00 | 13:30:00 |
    |  4 | 08:00:00 | 14:00:00 |
    |  5 | 08:30:00 | 14:30:00 |
    |  6 | 09:00:00 | 15:00:00 |
    |  7 | 09:30:00 | 15:30:00 |
    |  8 | 10:00:00 | 16:00:00 |
    |  9 | 10:30:00 | 16:30:00 |
    | 10 | 11:00:00 | 17:00:00 |
    | 11 | 11:30:00 | 17:30:00 |
    | 12 | 12:00:00 | 18:00:00 |
    | 13 | 12:30:00 | 18:30:00 |
    | 14 | 13:00:00 | 19:00:00 |
    | 15 | 13:30:00 | 19:30:00 |
    | 16 | 14:00:00 | 20:00:00 |
    | 17 | 14:30:00 | 20:30:00 |
    | 18 | 15:00:00 | 21:00:00 |
    | 19 | 15:30:00 | 21:30:00 |
    | 20 | 16:00:00 | 22:00:00 |
    | 21 | 16:30:00 | 22:30:00 |
    | 22 | 17:00:00 | 23:00:00 |
    | 23 | 17:30:00 | 23:30:00 |
    | 24 | 18:00:00 | 24:00:00 |
    +----+----------+----------+
    --------------
    drop table if exists `periode`
    --------------
     
    --------------
    CREATE TABLE `periode`
    ( `id`         integer unsigned  NOT NULL AUTO_INCREMENT Primary Key,
      `peri_date`  date              NOT NULL,
      `peri_deb`   time              NOT NULL,
      `peri_fin`   time              NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `periode` (`peri_date`,`peri_deb`,`peri_fin`) values
      ('2016-08-31','07:30:00','09:30:00'),
      ('2016-08-31','13:30:00','15:30:00')
    --------------
     
    --------------
    select * from periode
    --------------
     
    +----+------------+----------+----------+
    | id | peri_date  | peri_deb | peri_fin |
    +----+------------+----------+----------+
    |  1 | 2016-08-31 | 07:30:00 | 09:30:00 |
    |  2 | 2016-08-31 | 13:30:00 | 15:30:00 |
    +----+------------+----------+----------+
    --------------
    select *
    from (
        SELECT p1.peri_date, t.*, count(p1.peri_date) as nbre
     
        FROM       periode as p1
        CROSS JOIN test    as t
     
        WHERE NOT ((t.time_deb < p1.peri_fin and t.time_fin > p1.peri_deb))
          AND       p1.peri_date = '2016-08-31'
        GROUP BY t.id
    ) as x
    where nbre = (select count(p2.peri_date) from periode as p2 where p2.peri_date = x.peri_date)
    --------------
     
    +------------+----+----------+----------+------+
    | peri_date  | id | time_deb | time_fin | nbre |
    +------------+----+----------+----------+------+
    | 2016-08-31 | 19 | 15:30:00 | 21:30:00 |    2 |
    | 2016-08-31 | 20 | 16:00:00 | 22:00:00 |    2 |
    | 2016-08-31 | 21 | 16:30:00 | 22:30:00 |    2 |
    | 2016-08-31 | 22 | 17:00:00 | 23:00:00 |    2 |
    | 2016-08-31 | 23 | 17:30:00 | 23:30:00 |    2 |
    | 2016-08-31 | 24 | 18:00:00 | 24:00:00 |    2 |
    +------------+----+----------+----------+------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    Comme tu peux le voir dans la requête, j'ai procédé à un produit cartésien entre la table "periode" et la table "test".
    Pour extraire les plages horaires, j'ai comptabilisé les lignes qui sont communes à chaque ligne de la table "periode".
    De ce fait, s'il y a trois lignes dans "periode", il y aura normalement trois lignes en commun pour la même plage horaire.

    Si le résultat ne te retourne rien, c'est qu'il n'y a aucune ligne commune à chaque période.
    Ou si tu préfères, tu auras seulement deux lignes, une ligne, voire aucune, et non les trois attendues.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus24,

    Merci tout d'abord à nouveau pour tes explications que j'ai bien intégré.

    J'ai donc compris le fonctionnement de ton process, je l'ai testé avec des variables et les données retournées sont bien exactes !

    Il faut à présent que j'arrive à intégrer cela dans mon framework Fabrik et c'est là que cela s'avère difficile.

    Dans mon element | champ datepicker "book_bookingdate", j'avais créé un script PHP qui me permettait de vérifier dans la table "fab_booking" s'il existait au moins une réservation.

    Si c'était le cas, alors les dates étaient désactivées et l'utilisateur ne pouvait cliquer dessus (la date est grisée).
    Si aucune réservation existait, alors les dates étaient activées et l'utilisateur pouvaient cliquer dessus.

    Code PHP injecté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    $myDb = JFactory::getDbo();
    $myQuery = $myDb->getQuery(true);
    $myQuery
        ->select ('DATE(book_bookingdate)')
        ->from('fab_booking');
     
    $myDb->setQuery($myQuery);
    $bookedDates = $myDb->loadColumn();
     
    $begin = new DateTime();
    $end = new DateTime('2026-12-31');
     
    $interval = DateInterval::createFromDateString('1 day');
    $period = new DatePeriod($begin, $interval, $end);
     
    $myAllowedDates = array();
     
    foreach( $period as $dt ) {
        $thisDate = $dt->format("Y-m-d");
        if (!in_array($thisDate, $bookedDates)) {
        $myAllowedDates[] = $thisDate;
        }
    }
    return $myAllowedDates;
    Etant donné que je dois en premier lieu uniquement afficher les dates dans l'élément | le champ en question pour lesquelles il existe au moins une plage horaire de 6 heures, il faut que j'arrive à intégrer les différentes queries dans le champ d'injection PHP de l'élément | du champ prévu à cet effet.

    1. J'ai essayé de reprendre ton code et de créer des tables temporaires, afin d'éviter de devoir à chaque fois recréer des tables physiques. Mais une erreur m'indique que j'utilise deux fois la même table lorsque la requête suivante est traitée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select id,DATE_FORMAT(heuredepart_resa,'%H:%i') as heuredepart_resa from ( SELECT p1.book_date, t.*, count(p1.book_date) as nbre FROM fab_booking_taken as p1 CROSS JOIN fab_booking_slots as t WHERE NOT ((t.heuredepart_resa < p1.book_end and t.heurearrivee_resa > p1.book_start)) AND p1.book_date = '2016-08-15' GROUP BY t.id ) as x where nbre = (select count(p2.book_date) from fab_booking_taken as p2 where p2.book_date = x.book_date);
    J'ai bien sûr trouvé l'explication dans le manuel en ligne MYSQL

    This error also occurs if you refer to a temporary table multiple times in a stored function under different aliases, even if the references occur in different statements within the function.
    mais je suis honnêtement incapable de résoudre ce problème.

    2. Mettons que je trouve une solution à ce problème, je dois réadapter mon code PHP ci-dessous pour que le datepicker n'active que les dates pour lesquelles il existe bien au moins une plage horaire de 6 heures.

    Là également je suis dans l'incapacité de résoudre cela.

    3. Lorsque cela sera fait, je devrais peupler ma dropdown avec les heures de début des plages horaires libres, mais cela viendra après avoir résolu ces deux problèmes.

    Je suis bien conscient que cela demande du temps, mais je nécessite une solution et je suis prêt à rémunérer pour ce travail.

    Merci d'avance pour ton retour et bonne journée, Marc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    CREATE TEMPORARY TABLE `fab_booking_slots` (
    `id` int(10) unsigned NOT NULL,
      `heuredepart_resa` time NOT NULL,
      `heurearrivee_resa` time NOT NULL
    ) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ROW_FORMAT=COMPRESSED;
     
    INSERT INTO `fab_booking_slots` (`id`, `heuredepart_resa`, `heurearrivee_resa`) VALUES
    (1, '06:30:00', '12:30:00'),
    (2, '07:00:00', '13:00:00'),
    (3, '07:30:00', '13:30:00'),
    (4, '08:00:00', '14:00:00'),
    (5, '08:30:00', '14:30:00'),
    (6, '09:00:00', '15:00:00'),
    (7, '09:30:00', '15:30:00'),
    (8, '10:00:00', '16:00:00'),
    (9, '10:30:00', '16:30:00'),
    (10, '11:00:00', '17:00:00'),
    (11, '11:30:00', '17:30:00'),
    (12, '12:00:00', '18:00:00'),
    (13, '12:30:00', '18:30:00'),
    (14, '13:00:00', '19:00:00'),
    (15, '13:30:00', '19:30:00'),
    (16, '14:00:00', '20:00:00'),
    (17, '14:30:00', '20:30:00'),
    (18, '15:00:00', '21:00:00'),
    (19, '15:30:00', '21:30:00'),
    (20, '16:00:00', '22:00:00'),
    (21, '16:30:00', '22:30:00'),
    (22, '17:00:00', '23:00:00'),
    (23, '17:30:00', '23:30:00'),
    (24, '18:00:00', '24:00:00');
     
    CREATE TEMPORARY TABLE `fab_booking_taken` (
    `id` int(10) unsigned NOT NULL,
      `book_date` date NOT NULL,
      `book_start` time NOT NULL,
      `book_end` time NOT NULL
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ROW_FORMAT=COMPRESSED;
     
    insert into fab_booking_taken (book_date,book_start,book_end) SELECT book_bookingdate as book_date, book_crewstartdate as book_start, book_crewenddate as book_end FROM fab_booking WHERE DATE_FORMAT(book_crewstartdate,'%Y-%m-%d') = '2016-08-15' AND ('2016-08-15 06:30:00' >= book_crewstartdate AND '2016-08-15 06:30:00' < book_crewenddate OR (book_crewstartdate >= '2016-08-15 06:30:00' AND book_crewstartdate < '2016-08-16 00:00:01')) ORDER BY book_crewstartdate;
     
    select id,DATE_FORMAT(heuredepart_resa,'%H:%i') as heuredepart_resa from ( SELECT p1.book_date, t.*, count(p1.book_date) as nbre FROM fab_booking_taken as p1 CROSS JOIN fab_booking_slots as t WHERE NOT ((t.heuredepart_resa < p1.book_end and t.heurearrivee_resa > p1.book_start)) AND p1.book_date = '2016-08-15' GROUP BY t.id ) as x where nbre = (select count(p2.book_date) from fab_booking_taken as p2 where p2.book_date = x.book_date);

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut marc-q.

    Citation Envoyé par marc-q
    1. J'ai essayé de reprendre ton code et de créer des tables temporaires, afin d'éviter de devoir à chaque fois recréer des tables physiques.
    Il n'est pas nécessaire de créer une table avec le qualificatif "temporary".
    Il suffit de la créer normalement, et quand vous n'en as plus besoin, vous pouvez la détruire en faisant un "drop table if exists `fab_booking_taken`".
    Cela évitera le genre d'erreur que vous rencontrez.

    Une table temporaire, c'est externaliser une grosse sous-requête dans une requête pour une durée courte dans son utilisation.
    C'est ce que l'on peut nommer, une table de travail.

    En quoi devez-vous recréer à chaque fois vos tables physiques ?
    Vous avez besoin d'une table contenant la liste de toutes vos tranches horaires.
    En fait, vous avez besoin soit d'une table ou soit d'une procédure stockée qui va réaliser le même travail.
    La procédure stockée est plus lourde en terme de performance.
    Et puis, si vous devez, disons ajouter de nouvelles tranches horaires, il est plus facile de modifier le contenu d'une table que de modifier une procédure stockée.

    Citation Envoyé par marc-q
    le datepicker n'active que les dates pour lesquelles il existe bien au moins une plage horaire de 6 heures.
    N'est-ce pas ce que fait déjà mon exemple ? Je ne comprends pas bien votre problème d'activation.
    Si vous avez une tranche horaire de libre, en quoi est-ce si compliqué de l'activer ?
    Il me manque des informations pour bien comprendre vos difficultés.

    Citation Envoyé par marc-q
    je suis prêt à rémunérer pour ce travail.
    Nous sommes là pour aider les membres en difficulté et non se faire rémunérer.
    Le mieux est de poser correctement le problème afin de trouver une solution à vos difficultés.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus24,

    Merci pour tes conseils avisés et la précision de tes suggestions, car cela fonctionne parfaitement , mis à part un dernier souci que je t'exposerai plus bas.

    J'ai créé la table "fab_booking_slots" qui contient les plages horaires possibles.
    J'ai créé la table "fab_booking_taken" qui est peuplé à chaque création d'une nouvelle réservation. Lorsqu'une réservation est effacée, la ligne correspondante est effacée de la table. Si une modification est effectuée, la ligne correspondante est mise à jour.

    J'arrive à présent à peupler ma liste déroulante avec les valeurs correctes grâce à la requête suivante que j'injecte via l'élément "book_starttime" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE {thistable}.id IN (SELECT id +3 FROM (SELECT p1.book_date, t.*, count(p1.book_date) AS nbre FROM fab_booking_taken AS p1 CROSS JOIN fab_booking_slots AS t WHERE NOT ((t.heuredepart_resa < p1.book_end AND t.heurearrivee_resa > p1.book_start)) AND p1.book_date = '{fab_booking___book_bookingdate}' GROUP BY t.id ) AS x WHERE nbre = (SELECT count(p2.book_date) FROM fab_booking_taken AS p2 WHERE p2.book_date = x.book_date))
    "WHERE {thistable}.id" : correspond à la table qui est liée à l'élément et qui contient les heures de départ possibles."

    "SELECT id +3" : sachant qu'une réservation nécessite une plage horaire de 6 heures (1 1/2 heure pour la préparation de l'embarcation, 3 heures pour la sortie, 1 1/2 heure pour la remise en état de l'embarcation), si la plage horaire débute à 06:30, la réservation effective du client est de 08:00 à 11:00, je dois donc afficher non "06:30", mais "08:00". Ce n'est peut-être pas l'état de l'art, mais cela fonctionne correctement.

    "{fab_booking___book_bookingdate}" : il s'agit d'un placeholder qui reprend la date sélectionnée par le client dans l'élément datepicker

    A présent, j'ai un dernier souci.

    Cette requête ne retourne des options que si j'ai une valeur à comparer dans la table "fab_booking_taken", si pour la date choisi il n'existe aucune valeur, alors aucune option n'est affichée dans la liste déroulante. Alors qu'il faudrait que toutes les options possibles s'affichent soit les 24 plages horaires possibles.

    La règle serait donc :

    IF not empty exécuter cette WHERE CLAUSE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE {thistable}.id IN (SELECT id +3 FROM (SELECT p1.book_date, t.*, count(p1.book_date) AS nbre FROM fab_booking_taken AS p1 CROSS JOIN fab_booking_slots AS t WHERE NOT ((t.heuredepart_resa < p1.book_end AND t.heurearrivee_resa > p1.book_start)) AND p1.book_date = '{fab_booking___book_bookingdate}' GROUP BY t.id ) AS x WHERE nbre = (SELECT count(p2.book_date) FROM fab_booking_taken AS p2 WHERE p2.book_date = x.book_date))
    ELSE exécuter cette WHERE CLAUSE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE {thistable}.id IN (SELECT id +3 FROM fab_booking_slots)
    Aurais-tu une idée comment réaliser cela ?

    Merci d'avance pour ton expertise.

    Bonne journée, Marc

  8. #8
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut marc-q.

    Je ne connais pas le framework Fabrik donc je ne pourrai pas t'aider en ce qui concerne la partie développement.

    Citation Envoyé par marc-q
    Cette requête ne retourne des options que si j'ai une valeur à comparer dans la table "fab_booking_taken", si pour la date choisi il n'existe aucune valeur, alors aucune option n'est affichée dans la liste déroulante. Alors qu'il faudrait que toutes les options possibles s'affichent soit les 24 plages horaires possibles.
    L'idée que tu exposes est bonne !
    La seule chose que tu dois tester, c'est le nombre de lignes retournées par ta première requête.
    --> http://php.net/manual/fr/function.mysql-num-rows.php
    --> http://uk1.php.net/manual/en/pdostatement.rowcount.php

    Si ce nombre est égale à zéro, et bien tu exécutes la seconde requête sinon tu ne l'exécutes pas.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  9. #9
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus24

    Merci beaucoup pour ton aide, car cela fonctionne parfaitement lors de la création d'une réservation.

    J'arrive à créer des réservations, lorsqu'une réservation existe pour une date donnée, alors seuls les plages disponibles sont bien retournées. Lorsqu'aucune réservation existe, alors toutes les plages disponibles sont également bien retournées.

    Par contre, j'avais totalement zappé l'édition par la suite d'une réservation. Effectivement des modifications peuvent être apportées par l'administration après la réservation effectuée et enregistrée. Entre autres, l'administrateur doit pouvoir changer la plage horaire pour autant qu'une plage horaire disponible existe.

    Mettons que j'ai d'ores et déjà une plage horaire réservée de 06:30 à 12:30 pour un jour X.

    La requête ne retourne naturellement que les plages horaires de 6 heures disponibles, car elle pour elle la plage horaire de 06:30 à 12:30 est déjà enregistrée dans la table "fab_booking_taken".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    14:00
    14:30
    15:00
    15:30
    16:00
    16:30
    17:00
    17:30
    18:00
    Requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE {thistable}.id IN (SELECT id +3 FROM (SELECT p1.book_date, t.*, count(p1.book_date) AS nbre FROM fab_booking_taken AS p1 CROSS JOIN fab_booking_slots AS t WHERE NOT ((t.heuredepart_resa < p1.book_end AND t.heurearrivee_resa > p1.book_start)) AND p1.book_date = '{fab_booking___book_bookingdate}' GROUP BY t.id ) AS x WHERE nbre = (SELECT count(p2.book_date) FROM fab_booking_taken AS p2 WHERE p2.book_date = x.book_date))
    Pour info, afin d'afficher dans la dropdown l'heure effective de début de réservation pour le client soit 01:30 après l'arrivée de l'équipage, j'incrémente l'id +3. Ainsi si la plage horaire réservée est de 06:30 à 12:30, l'heure de début effective de la réservation sera donc 08:00'
    La dropdown devrait également me retourner la valeur correspondant à la valeur déjà renseignée dans le champ "book_starttime" de la table "fab_booking" ainsi les plages horaires de 6 heures disponibles à savoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    08:00 <- valeur enregistrée lors de la réservation
    14:00
    14:30
    15:00
    15:30
    16:00
    16:30
    17:00
    17:30
    18:00
    Effectivement, l'utilisateur doit retrouver la valeur enregistrée lors de la réservation, ainsi que les autres plages horaires disponibles, afin le cas échéant de pouvoir choisir une autre plage horaire ou conserver la valeur d'ores et déjà enregistrée.

    La requête identifie donc un record dont la date correspond à la date de réservation de la réservation éditée dans la table "fab_booking_taken", elle ne retourne alors que les plages horaires encore disponibles, ce qu'elle est censée faire.

    Il faudrait que la requête affiche tout de même la plage horaire d'ores et déjà réservée en plus des plages horaires disponibles.

    J'aurais besoin de ton aide pour ce dernier point, car cela reste encore assez complexe pour moi d'intégrer ce paramètre dans une requête imbriquée d'ores et déjà complexe pour moi. Il faudrait effectivement que la requête identifie tout d'abord bien qu'une réservation existe pour la date donnée, puis retourne néanmoins la valeur de la plage horaire existante, plus les valeurs des autres plages disponibles.

    Merci d'avance de ton retour en espérant avoir été clair dans mes explications.

    Marc

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 379
    Points : 19 060
    Points
    19 060
    Par défaut
    Salut marc-q.

    En fait, tu as deux requêtes :
    1) celle qui va te donner la plage horaire déjà réservée.
    2) celle qui va te donner les plages horaires disponibles.

    Pour fusionner les deux requêtes, il faut utiliser la clause "union".
    --> http://dev.mysql.com/doc/refman/5.7/en/union.html

    Les deux requêtes doivent posséder les mêmes noms de colonnes et le même nombre de colonnes, sinon ça va coincer.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus24,

    Merci pour ton retour et tes explications. J'ai essayé de créer cette requête mais sans résultat probant.

    Ma requête qui me retourne la valeur déjà réservé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (SELECT id +3 FROM (SELECT p1.book_date, t.*, count(p1.book_date) AS nbre FROM fab_booking_taken AS p1 CROSS JOIN fab_booking_slots AS t WHERE ((t.heuredepart_resa < p1.book_end AND t.heurearrivee_resa > p1.book_start)) AND t.id = '{fab_booking___book_starttime}' AND p1.book_date = '{fab_booking___book_bookingdate}' GROUP BY t.id ) AS x WHERE nbre = (SELECT count(p2.book_date) FROM fab_booking_taken AS p2 WHERE p2.book_date = x.book_date))
    AND t.id = '{fab_booking___book_starttime}'
    doit me retourner la valeur id de la table fab_booking_slots enregistrée dans le champ "book_starttime" de ma table "fab_booking.

    Mais j'ai bien sûr le message d'erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    The used SELECT statements have a different number of columns SQL=SELECT DISTINCT(`fab_booking_slots_0`.`id`) AS value, CONCAT_WS('', DATE_FORMAT(`fab_booking_slots_0`.heuredepart_resa, '%H:%i')) AS text FROM `fab_booking_slots` AS `fab_booking_slots_0` WHERE `fab_booking_slots_0`.id IN (SELECT id +3 FROM (SELECT p1.book_date, t.*, count(p1.book_date) AS nbre FROM fab_booking_taken AS p1 CROSS JOIN fab_booking_slots AS t WHERE NOT ((t.heuredepart_resa < p1.book_end AND t.heurearrivee_resa > p1.book_start)) AND p1.book_date = '2016-09-12 20:32:45' GROUP BY t.id ) AS x WHERE nbre = (SELECT count(p2.book_date) FROM fab_booking_taken AS p2 WHERE p2.book_date = x.book_date)) UNION (SELECT id +3 FROM (SELECT p1.book_date, t.*, count(p1.book_date) AS nbre FROM fab_booking_taken AS p1 CROSS JOIN fab_booking_slots AS t WHERE ((t.heuredepart_resa < p1.book_end AND t.heurearrivee_resa > p1.book_start)) AND t.id = '08:00' AND p1.book_date = '2016-09-12 20:32:45' GROUP BY t.id ) AS x WHERE nbre = (SELECT count(p2.book_date) FROM fab_booking_taken AS p2 WHERE p2.book_date = x.book_date)) ORDER BY text ASC
    A savoir que j'ai un nombre de colonnes différent.

    Tout d'abord

    1. Est-ce que ma requête retournant la valeur déjà enregistrée te semble correcte ?
    2. Est-ce que la manière dont j'ai "UNIONé" mes deux requêtes est la bonne manière ?
    3. Est-ce
    AND t.id = '{fab_booking___book_starttime}'
    que la requête considère être une colonne en plus ?

    Ces requêtes imbriquées restent encore très complexes pour moi et j'apprécierai encore un coup de pouce, afin que je puisse enfin finaliser le tout.

    Merci d'avance de ta patience et de ton expertise.

    Marc

  12. #12
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus24,

    Je suis encore dans la panade avec cette requête UNION, je ne te demande naturellement pas de me livrer la solution, mais j'ai encore besoin d'un petit coup de pouce qui serait grandement apprécié.

    Merci d'avance de ton retour.

    Marc

  13. #13
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2016
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Vietnam

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2016
    Messages : 30
    Points : 13
    Points
    13
    Par défaut
    Bonjour Artemus 24,

    Je reviens vers vous car je ne trouve pas la solution, je n'arrive pas à afficher avec une requête union les plages horaires disponibles ainsi que la valeur d'ores et déjà enregistrée dans la table correspondante.

    J'ai demandé aux développeurs de Fabrik (http://fabrikar.com/) le framework que j'utilise d'intervenir. Il s'agit de développeurs confirmés et ils n'ont pas trouvé la solution comme vous pourrez le voir dans le thread suivant :

    http://fabrikar.com/forums/index.php...1/#post-232986.

    Je suis donc dans l'incapacité de finaliser mon application.

    J'ai bien compris que vous ne souhaitiez apparemment plus intervenir sur ce sujet au regard de votre silence persistant, par contre je réitère ma proposition de rémunérer pour ce travail.

    Merci donc simplement de vous manifester, afin que je sache à quoi m'en tenir.

    Marc

Discussions similaires

  1. [XL-2007] Afficher heure d'1 plage horaire dans combobox
    Par stephadm dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 16/04/2012, 19h00
  2. convertir des heures selon les fuseaux horaires
    Par cyrano_de_bergerac dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 27/05/2008, 11h13
  3. Afficher les valeurs d'une plage
    Par Bono_BX dans le forum SAP Crystal Reports
    Réponses: 0
    Dernier message: 14/09/2007, 11h47
  4. Afficher les milièmes dans un champs Date Heure
    Par zooffy dans le forum ASP.NET
    Réponses: 8
    Dernier message: 27/07/2007, 14h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo