Partage
  • Partager sur Facebook
  • Partager sur Twitter

[MySQL 5.7] Requête différence entre 2 dates

Avec plusieurs critère

    24 février 2021 à 18:21:40

    Bonjour à tous,

    Je viens solliciter votre aide, car je cherche un moyen de réaliser une requête assez spéciale, mais je ne sais vraiment pas comment m'y prendre.

    J'ai une Table déclaration qui est réalisée comme ceci :

     

    J'aimerais dans ma requête extraire qu'une colonne totale se fasse et qu'elle me calcule la différence entre 2 dates.

    Mais il faut avant que la requête soi trier par nom asc, dates asc pour qu'il fasse la comparaison par nom, et s'il y a une Fin de poste de détecter, il ne calcule pas le temps

    Voilà en gros le résultat que j'aimerais en sortir :

    Comment faire cela ?

    Je ne sais même pas si c'est faisable à vrai dire.

    Merci d'avance 

    • Partager sur Facebook
    • Partager sur Twitter
      24 février 2021 à 18:29:09

      Bonjour,

      Je ne comprends les date/heure qu'il faut comparer ?

      Celle de la tâche suivante pour le même nom c'est ça ?

      Comment déterminer quelle tâche est la suivante dans ce cas ? Juste avec son libellé ? Ou bien la table en question (la vraie) dispose d'un identifiant, voire d'un ordre ?

      Peux-tu poster la structure réelle de la ou les tables concernées ?

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        24 février 2021 à 18:57:17

        Bonjour,

        Merci pour la réponse si rapide :) 

        DROP TABLE IF EXISTS `declaration`;
        CREATE TABLE IF NOT EXISTS `declaration` (
          `id` int(11) NOT NULL AUTO_INCREMENT,
          `id_affaires` int(11) NOT NULL,
          `id_users` int(11) NOT NULL,
          `username` varchar(255) NOT NULL,
          `tache` varchar(50) NOT NULL,
          `etat` tinyint(4) NOT NULL,
          `dates` datetime NOT NULL,
          PRIMARY KEY (`id`)
        ) ENGINE=MyISAM AUTO_INCREMENT=255 DEFAULT CHARSET=utf8;
        
        --
        -- Déchargement des données de la table `declaration`
        --
        
        INSERT INTO `declaration` (`id`, `id_affaires`, `id_users`, `username`, `tache`, `etat`, `dates`) VALUES
        (254, 2, 4, 'Gitton Anne-Charlotte', 'Interchantier', 0, '2021-02-24 17:27:31'),
        (253, 11, 4, 'Gitton Anne-Charlotte', 'Fin de poste', 0, '2021-02-24 22:15:00'),
        (252, 2, 4, 'Colotte Kevin', 'Bureau', 0, '2021-02-24 18:15:00'),
        (251, 2, 4, 'Jardine Guy', 'Bureau', 0, '2021-02-24 18:15:00'),
        (250, 2, 4, 'Gitton Natacha', 'Bureau', 0, '2021-02-24 18:15:00'),
        (249, 2, 4, 'Gitton Anne-Charlotte', 'Bureau', 0, '2021-02-24 18:15:00'),
        (248, 2, 4, 'Dumont Alexandre', 'Bureau', 0, '2021-02-24 18:15:00'),
        (247, 1, 4, 'Colotte Kevin', 'Bureau', 0, '2021-02-24 17:15:00'),
        (246, 1, 4, 'Jardine Guy', 'Bureau', 0, '2021-02-24 17:15:00'),
        (245, 1, 4, 'Gitton Natacha', 'Bureau', 0, '2021-02-24 17:15:00'),
        (244, 1, 4, 'Gitton Anne-Charlotte', 'Bureau', 0, '2021-02-24 17:15:00'),
        (243, 1, 4, 'Dumont Alexandre', 'Bureau', 0, '2021-02-24 17:15:00');
        COMMIT;

        Voilà ma base de donnée

        En fait la tache importe peut il doit juste détecter la fin de poste pour ne pas calculer le temps a ce moment là

        La table est en fait triée par nom, et ensuite date la fin de de poste sera toujours la dernière déclaration de la personne

        Je ne sais pas si je suis assez claire dans mon explication ^^ 

        • Partager sur Facebook
        • Partager sur Twitter
          24 février 2021 à 19:39:31

          Donc tu veux calculer pour chaque personne, le temps entre le premier pointage et le dernier pointage pour chaque jour ?

          Dans ton exemple, on voit que tu laisses les pointages intermédiaires... c'est voulu ?

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            24 février 2021 à 19:51:52

            Je me suis mal exprimé désolé :)
            J'ai besoin d'afficher tous les pointages et ce que je veux calculer, c'est bien chaque ligne pour ensuite pouvoir filtrer mes taches et voir les totaux de chacune d'elles.
            Comme le trie par le nom et ensuite les dates, je vais forcement avoir un tri dans le bon ordre chrono de chaque personne et ensuite la requête fais la différence de chaque ligne
            • Partager sur Facebook
            • Partager sur Twitter
              24 février 2021 à 21:28:07

              Donc il faut bien calculer le temps entre 2 tâches... du coup on revient sur ma question de départ, comment déterminer la tâche suivante de chaque pointage ... uniquement par l'heure ?

              La colonne "résultat" dans ton exemple est bien la différence entre l'heure de la tâche 2 et celle de la tâche 1 ...

              -
              Edité par Benzouye 24 février 2021 à 21:29:36

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                24 février 2021 à 21:46:54

                Ah oui 

                C'est effectivement que par l'heur 

                C'est bien ça ;)

                • Partager sur Facebook
                • Partager sur Twitter
                  25 février 2021 à 10:09:00

                  Une première solution "simple" est d'incrémenter une variable de session :

                  SELECT
                  	IF( username = @nom_precedent, dates - @date_precedente, '00:00:00' ) AS resultat
                  	tache,
                  	@date_precedente := dates AS dates
                  	@nom_precedent := username AS username
                  FROM
                  	( SELECT @nom_precedent := '', @date_precedente := '' ) AS tmp,
                  	declaration
                  ORDER BY username, dates

                  Au passage, je dirais qu'il serait bien de créer une table "utilisateur" avec les différents username possibles, et une table "tâche" avec les différentes tâches possibles, et de n'avoir dans la table déclaration que les id correspondant, c'est plus rigoureux et normalisé ...

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                    25 février 2021 à 13:40:43

                    Bonjour,

                    J'ai bien une base Table users et la table tache je pensais bientôt le faire c'est prévu de reprendre l'id :) 

                    Merci du conseil

                    SELECT
                        IF( username = @nom_precedent, dates - @date_precedente, '00:00:00' ) AS resultat,
                        tache,
                        @date_precedente:=dates AS dates,
                        @nom_precedent:=username AS username
                    FROM
                        ( SELECT @nom_precedent := '', @date_precedente := '' ) AS tmp,
                        declaration
                    ORDER BY username, dates

                    Le code avait une erreur et dans mon réseau interne d'entreprise qu'ils mon créer ce matin je n'ai que MariaDb du coup j'ai du faire quelque changement

                    cependant mon résultat me retourne : 

                     Du coup je pense que c'est un timestamp j'aurais juste besoin du résultat en temps h:i

                    Merci beaucoup du coup de main :) j'essai de comprendre le fonctionnement 

                    -
                    Edité par Lecorsiau88 25 février 2021 à 13:41:12

                    • Partager sur Facebook
                    • Partager sur Twitter
                      25 février 2021 à 15:13:05

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                        25 février 2021 à 18:37:50

                        SELECT
                            IF( username = @nom_precedent, TIME_FORMAT(TIMEDIFF(@date_precedente,dates),'%H:%i'), '00:00:00' ) AS resultat,
                            tache,id,etat,id_affaires,
                            @date_precedente:=dates AS dates,
                            @nom_precedent:=username AS username
                        FROM
                            ( SELECT @nom_precedent := '', @date_precedente := '' ) AS tmp,
                            declaration
                        ORDER BY username, dates desc

                        Impec ;) Merci beaucoup pour votre aide
                        J'aurais encore un question
                        Je cherche comment je pourrais faire affiché plusieurs jours de la semaine mais qu'il ne me compte pas les fin de poste
                        Car par exemple il détecte la fin de poste à 25/02/2021 18h00

                        Si dans un tableau ou je désire affiché plus que la journée actuel j'aurais un pointage en début de journée à 26/02/2021 07:00
                        Du coup actuellement il va me faire un temps pour la fin de poste de : 26/02/2021 07:00 - 25/02/2021 18:00
                        Je sais pas je suis assez clair
                        Édit : a quoi correspond le @ ?

                        -
                        Edité par Lecorsiau88 25 février 2021 à 18:51:11

                        • Partager sur Facebook
                        • Partager sur Twitter
                          25 février 2021 à 21:13:37

                          Le @ sert à définir une variable de session.

                          Apres je ne comprends pas ta question. Poste un exemple de données et le résultat attendu.

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                            25 février 2021 à 21:56:22

                            Ok merci de l'info :)

                            Voici le résultat attendu

                            Dans l'image du dessus voici en gros ce que je sort actuellement

                            au niveau de mon fin de poste quand j'ai un temps qui ne devrais pas etre calculé car cette fin de poste ne doi pas avoir de valeur il sert juste a faire le calcul de fin de poste - mur rdc 

                            Par contre si j'affiche un autre jour dans la table en plus, forcement il va m'ajouté les nouveau scan sauf que le premier calcul va prendre le fin de poste de la veille 

                            et ca ne peux pas fonctionné

                            • Partager sur Facebook
                            • Partager sur Twitter
                              26 février 2021 à 8:25:49

                              Je n'ai toujours pas compris ...

                              Dans ton screen les dates dont triées décroissant... normal ?

                              Quel serait le résultat attendu ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                26 février 2021 à 14:48:19

                                Alors je ne pensais pas réutilisé un jour le logiciel PAINT mais c'est chose faite (du grand art) ^^

                                Alors j'ai écrit à gauche des temps ce que j'aimerais pouvoir avoir.

                                Comme on change de jour on ne peu pas continuer le calcul après une fin de poste (en gros c'est la fin de journée de la personne)

                                Forcement le calcul prochain sera un autre jour et donc il ne faut pas qu'il fasse la différence entre la date de fin de poste et la date du prochain jour

                                Pour le Desc, c'est juste que le visuel est finalement mieux ainsi :)

                                -
                                Edité par Lecorsiau88 26 février 2021 à 14:49:35

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  26 février 2021 à 18:30:21

                                  Du coup il faut également tester le changement de date en plus du changement de nom.

                                  SELECT
                                  	IF(
                                  		username = @nom_precedent
                                  		AND DATE( dates ) = @jour_precedent,
                                  		TIME_FORMAT(TIMEDIFF(@date_precedente,dates),'%H:%i'),
                                  		'00:00:00'
                                  	) AS resultat,
                                  	tache,id,etat,id_affaires,
                                  	@jour_precedent:= DATE( dates ) AS jour,
                                  	@date_precedente:=dates AS dates,
                                  	@nom_precedent:=username AS username
                                  FROM
                                  	( SELECT @nom_precedent := '', @jour_precedent := '', @date_precedente := '' ) AS tmp,
                                  	declaration
                                  ORDER BY username, dates desc

                                  J'ai compris ?

                                  -
                                  Edité par Benzouye 12 mars 2021 à 14:00:29

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                    27 février 2021 à 8:38:44

                                    Bonjour,

                                    c'est bizarre en regardant ton code je me dit c'est logique cela devrais fonctionné 

                                    mais finalement j'ai le même résultat j'ai essayer plusieurs modification mais sans résultat

                                    voila ce que j'obtiens 

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      27 février 2021 à 11:07:39

                                      Les conditions du IF ne sont pas bonnes...

                                      Il faut mettre un AND au lieu d'un OR, et un = au lieu d'un <>.

                                      Essaye voir.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                        12 mars 2021 à 13:20:10

                                        Je viens de voir que je n'ai pas répondu, c'est plutôt étrange, j'étais persuadé de l'avoir fait.

                                        Désolé ...

                                        Superbe boulot ca fonctionne à merveille, merci beaucoup pour le temps que vous m'avez accordé.

                                        Vous pensez que si je veux sortir ce même tableau mais avec la somme du total par date, c'est réalisable dans la même requête ? 

                                        -
                                        Edité par Lecorsiau88 12 mars 2021 à 13:20:43

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          12 mars 2021 à 14:01:04

                                          C'est mieux de le faire côté application dans la boucle de traitement des lignes.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                            12 mars 2021 à 15:43:01

                                            J'ai fais des essai justement dans mon code php mais pas moyen

                                            Je vois pas comment regroupé par date et faire le total en fonctionne de celle-ci

                                            			<?php
                                            
                                            			  while ($row = $resultSet->fetch(PDO::FETCH_ASSOC)) {
                                            			?>
                                            
                                            			<?php
                                            			if($row['etat'] == 0){
                                            				$couleur = "class=table-danger";
                                            			}
                                            			elseif($row['etat'] == 1){
                                            				$couleur = "class=table-warning";
                                            			}
                                            			else($row['etat'] == 2){
                                            				$couleur = "class=table-success"
                                            			}
                                            			?>
                                            			<tr>
                                            			  <td scope="row"><?php echo $row['id'];?></td>
                                            
                                            				<td  <?php echo $couleur;?>><?php echo $row['jour'];?></td>
                                            				<td  <?php echo $couleur;?>><?php echo $row['username'];?></td>
                                            				<td  <?php echo $couleur;?>><?php echo $row['nomaffaire'];?></td>
                                            				<td  <?php echo $couleur;?>><?php echo $row['tache'];?></td>
                                            				<td  <?php echo $couleur;?>><?php echo gmdate("H:i", $row['resultat']);?></td>
                                            			</tr>
                                            		<?php
                                            		}
                                            		?>



                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              12 mars 2021 à 16:43:56

                                              Directement en SQL :

                                              SELECT
                                              	IF(
                                              		username = @nom_precedent
                                              		AND DATE( dates ) = @jour_precedent,
                                              		TIME_FORMAT(TIMEDIFF(@date_precedente,dates),'%H:%i'),
                                              		'00:00:00'
                                              	) AS resultat,
                                              	tache,id,etat,id_affaires,
                                              	IF(
                                              		DATE( dates ) = @jour_precedent,
                                              		@cumul:= @cumul + TIME_FORMAT(TIMEDIFF(@date_precedente,dates),'%H:%i'),
                                              		@cumul:= 0
                                              	) AS cumul,
                                              	@jour_precedent:= DATE( dates ) AS jour,
                                              	@date_precedente:=dates AS dates,
                                              	@nom_precedent:=username AS username
                                              FROM
                                              	( SELECT @nom_precedent := '', @jour_precedent := '', @date_precedente := '', @cumul := 0 ) AS tmp,
                                              	declaration
                                              ORDER BY username, dates desc

                                              Cela ne rajoute pas une ligne pour le total ...

                                              Pour le coder en PHP, je te conseille de poster dans le forum PHP ...

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                                17 mars 2021 à 7:37:30

                                                Merci beaucoup pour votre aide

                                                je vais voir du coté PHP 

                                                Encore merci ! :)

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  15 avril 2021 à 7:37:05

                                                  Bonjour

                                                  Désolé pour le remontage de sujet,

                                                  J'ai une question, j'ai réalisé un inner join pour me ramener le nom du chantier

                                                  sauf que le calcul a cause du inner join ne se réalise pas correctement

                                                  Je réalise quelque chose de mal ? 

                                                  SELECT IF(
                                                          username = @nom_precedent
                                                          AND DATE( dates ) = @jour_precedent,
                                                          TIME_TO_SEC(TIMEDIFF(@date_precedente,dates)),
                                                          '0'
                                                      ) AS resultat,
                                                      tache,declaration.id,etat,nomaffaire,
                                                      @jour_precedent:= DATE( dates ) AS jour,
                                                      @date_precedente:=dates AS dates,
                                                      @nom_precedent:=username AS username
                                                  FROM
                                                      ( SELECT @nom_precedent := '', @jour_precedent := '', @date_precedente := '' ) AS tmp,
                                                      declaration INNER JOIN affaires ON declaration.id_affaires = affaires.id WHERE username = ? AND (DATE(dates)=DATE(now()))
                                                  ORDER BY username, dates desc

                                                  Merci d'avance

                                                  Antoine

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    15 avril 2021 à 9:17:23

                                                    Bonjour,

                                                    Je ne vois aucun problème de syntaxe, et vu que pour une déclaration une seule affaire est possible je ne vois pas de problème de données possible ...

                                                    SELECT
                                                    	IF(
                                                    		D.username = @nom_precedent
                                                    		AND DATE( D.dates ) = @jour_precedent,
                                                    		TIME_TO_SEC( TIMEDIFF( @date_precedente, dates ) ),
                                                    		'0'
                                                    	) AS resultat,
                                                    	D.tache,
                                                    	D.id,
                                                    	D.etat,
                                                    	A.nomaffaire,
                                                    	@jour_precedent := DATE( D.dates ) AS jour,
                                                    	@date_precedente := D.dates AS dates,
                                                    	@nom_precedent := D.username AS username
                                                    FROM
                                                    	( SELECT @nom_precedent := '', @jour_precedent := '', @date_precedente := '' ) AS tmp,
                                                    	declaration D
                                                    		INNER JOIN affaires A
                                                    			ON D.id_affaires = A.id
                                                    WHERE
                                                    	D.username = ?
                                                    	AND DATE( D.dates ) = CURDATE()
                                                    ORDER BY D.username, D.dates DESC

                                                    Lecorsiau88 a écrit:

                                                    le calcul a cause du inner join ne se réalise pas correctement

                                                    Peux-tu donner un exemple ?

                                                    -
                                                    Edité par Benzouye 15 avril 2021 à 9:18:03

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                                      16 avril 2021 à 11:38:51

                                                      Bonjour,

                                                      Merci pour la réponse ! :)

                                                      Deux exemple :

                                                      avec le code du script sans inner join :

                                                      et avec l'inner join :

                                                      Je ne comprend vraiment pas pourquoi le calcul réagi comme ca 

                                                      -
                                                      Edité par Lecorsiau88 16 avril 2021 à 11:50:48

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        16 avril 2021 à 11:59:05

                                                        Peux-tu poster le code SQL réel de ces deux requêtes ?

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                                          16 avril 2021 à 12:18:03

                                                          Bien sur,

                                                          Pour la première requêtes : 

                                                          SELECT IF(
                                                                  username = @nom_precedent
                                                                  AND DATE( dates ) = @jour_precedent,
                                                                  TIME_TO_SEC(TIMEDIFF(@date_precedente,dates)),
                                                                  '0'
                                                              ) AS resultat,
                                                              tache,id,etat,id_affaires,
                                                              @jour_precedent:= DATE( dates ) AS jour,
                                                              @date_precedente:=dates AS dates,
                                                              @nom_precedent:=username AS username
                                                          FROM
                                                              ( SELECT @nom_precedent := '', @jour_precedent := '', @date_precedente := '' ) AS tmp,
                                                              declaration WHERE username = ? AND (YEAR(dates) = YEAR(NOW())) AND (WEEK(dates) = WEEK(NOW()))
                                                            ORDER BY username, dates desc



                                                          Et la deuxième :

                                                          SELECT IF(
                                                                  username = @nom_precedent
                                                                  AND DATE( dates ) = @jour_precedent,
                                                                  TIME_TO_SEC(TIMEDIFF(@date_precedente,dates)),
                                                                  '0'
                                                              ) AS resultat,
                                                              tache,declaration.id,etat,nomaffaire,
                                                              @jour_precedent:= DATE( dates ) AS jour,
                                                              @date_precedente:=dates AS dates,
                                                              @nom_precedent:=username AS username
                                                          FROM
                                                              ( SELECT @nom_precedent := '', @jour_precedent := '', @date_precedente := '' ) AS tmp,
                                                              declaration INNER JOIN affaires ON declaration.id_affaires = affaires.id WHERE username = ? AND (YEAR(dates) = YEAR(NOW())) AND (WEEK(dates) = WEEK(NOW()))
                                                            ORDER BY username, dates desc



                                                          -
                                                          Edité par Lecorsiau88 16 avril 2021 à 12:18:35

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            16 avril 2021 à 12:39:36

                                                            Ce n'est pas possible ... Il y a forcément autre chose ... peut-être côté PHP ...

                                                            Peux-tu exécuter exactement ces deux requêtes dans PHPMyAdmin (ou autre GUI MySQL) et poster le résultat ?

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                                                              16 avril 2021 à 12:58:11

                                                              Oui je ne comprend vraiment pas :p

                                                              voila les 2 résultats dans phpmyadmin.

                                                              Avec inner

                                                              Sans inner

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              [MySQL 5.7] Requête différence entre 2 dates

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown