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 :

Dernière date sur plusieurs colonnes


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Mars 2012
    Messages : 34
    Points : 22
    Points
    22
    Par défaut Dernière date sur plusieurs colonnes
    Bonjour,
    J'ai une table qui se compose des colonnes suivantes :
    `id` primaire unique
    `Date` type date
    `Action` type text
    `réf` varchar 16
    `enCours` booléen

    `réf` identifie chaque `Action` effectuée sur cette référence avec la date de cette action.
    Je cherche à extraire la dernière action effectuée qui soit valide `enCours`=1 pour chacune des références.

    Voici des exemples qui ne fonctionnent pas, je galère depuis un moment et je m'adresse à vous.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $clauseWHERE="`enCours`='1'";
     
    $sqlETA="SELECT * FROM `CC_globale` WHERE $clauseWHERE GROUP BY `réf` ORDER BY `date_Action` DESC"
     
    $sqlETA="SELECT * FROM `CC_globale` WHERE ($clauseWHERE AND (`date_Action`=(SELECT MAX(`date_Action`)))) GROUP BY `réf` ORDER BY `date_Action` DESC";
     
    $sqlETA="SELECT * FROM `CC_globale` WHERE $clauseWHERE (GROUP BY `réf` WHERE `date_Action`>=MAX(`date_Action`)) ORDER BY `date_Action` DESC";
    Merci de bien vouloir m'aider.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 126
    Points : 28 535
    Points
    28 535
    Par défaut
    Bonjour ,

    C'est un problème classique en SQL, déjà résolu de nombreuses fois sur ce forum.
    Un billet de blog lui a même été consacré : Sélectionner la ligne la plus récente pour un critère.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Mars 2012
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Bonjour et merci pour votre réponse.
    Dans mes recherches j'avais déjà vu ce billet mais il ne convient pas à mon problème.
    Je n'ai qu'une table et je veux trouver la dernière ligne créée pour chaque `réf` dans cette unique table.
    Actuellement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sqlETA="SELECT * FROM `CC_globale` WHERE $clauseWHERE GROUP BY `réf` ORDER BY `date_Action` DESC";
    retourne :
    Nom : Champi01.jpg
Affichages : 64
Taille : 102,8 Ko

    ce qui est correct sauf pour les lignes 22 et 23, d'id 9 et id 4 dont ce n'est pas la dernière date.

  4. #4
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 281
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 281
    Points : 8 589
    Points
    8 589
    Billets dans le blog
    17
    Par défaut
    Je cherche à extraire la dernière action effectuée qui soit valide `enCours`=1 pour chacune des références.
    À partir de MySQL 8 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    WITH dataset (
        SELECT ALL
            id, ref, date, action,
            RANK() OVER (PARTITION BY ref ORDER BY date DESC) AS r
        FROM ta_table
        WHERE enCours = TRUE
    )
    SELECT ALL *
    FROM dataset
    WHERE r = 1
    Attention il peut y avoir plusieurs lignes par réf. s'il y a plusieurs actions avec une date max récurrente.
    Ajouter éventuellement un 2nd critère de tri dans le partitionnement ou utiliser ROW_NUMBER().

    https://dev.mysql.com/doc/refman/8.0...#function_rank

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Mars 2012
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Je vous remercie pour votre réponse, malheureusement mes bases de données sont hébergées chez OVH et sont en MYSQL v.5.7 donc bien loin de la V8.

  6. #6
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 281
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 281
    Points : 8 589
    Points
    8 589
    Billets dans le blog
    17
    Par défaut
    Avec une sous-requête et un MAX() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT ALL id, ref, date, action
    FROM ta_table
    WHERE (ref, date) IN (
        SELECT ALL ref, MAX(date)
        FROM ta_table
        WHERE enCours = TRUE
        GROUP BY 1
    );
    Cela fonctionne si tu n'as jamais 2 dates max identiques par référence.

    Tu peux aussi faire une sous-requête dans un INNER JOIN plutôt que dans le WHERE.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Mars 2012
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Je viens de tester et j'ai modifié car je ne sais pas ce qu'est un SELECT ALL et je ne trouve pas de doc qui tienne la route et j'avais des erreurs car les autres références n'étaient pas sélectionnées.
    J'ai donc remplacé ALL par *, mais alors j'ai eu l'erreur :

    Warning: PDO::query(): SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 2 column(s) in /home/lcegpyub/www/Champignons/ETAligneCC_actions.php on line 78

    Finalement je suis arrivé à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	SELECT *, id_CCG, réf, date_Action, action
    	FROM CC_globale
    	WHERE (réf, date_Action) IN (
    		 SELECT  réf, MAX(date_Action)
    		 FROM CC_globale
    		 WHERE enCours = TRUE
    		 GROUP BY 1
    	)
    qui fonctionne bien avec un doublon comme tu avais dit s'il y a 2 dates max identiques par référence.

    Au final j'arrive à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    	SELECT *, id_CCG, réf, date_Action, action
    	FROM CC_globale
    	WHERE (réf, date_Action) IN (
    		 SELECT  réf, MAX(date_Action)
    		 FROM CC_globale
    		 WHERE enCours = TRUE
    		 GROUP BY 1
    	)
    	GROUP BY réf
    qui à l'air de fonctionner correctement.

    Je ne comprend pas non plus le : GROUP BY 1 en plus du select ALL, si tu peux m'indiquer où je peux trouver de la doc, ce serait super.

    En tout cas je te remercie car il est évident que sans ton aide je n'en serai pas là.

  8. #8
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 281
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 281
    Points : 8 589
    Points
    8 589
    Billets dans le blog
    17
    Par défaut
    On retrouve ces infos dans la doc MySQL => https://dev.mysql.com/doc/refman/8.0/en/select.html

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT
        [ALL | DISTINCT | DISTINCTROW]
        ...
        [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
        ...
    ALL => C'est le modificateur par défaut, opposé à DISTINCT
    GROUP 1 => On groupe sur la 1re colonne

    Je ne comprends pas ton "SELECT *" accompagné de colonnes, le * ramenant déjà toutes les colonnes (ce qui est rarement vraiment nécessaire finalement).

    Attention, un GROUP BY devrait lister toutes les colonnes non agrégées, autrement le résultat est aléatoire, et la requête sera rejetée si un jour tu passes MySQL en mode strict (SET @@sql_mode = 'ANSI,TRADITIONAL';).

    Tu peux augmenter la précision de l'horodatage de tes actions à la microseconde en spécifiant tes colonnes en DATETIME(6).

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations forums :
    Inscription : Mars 2012
    Messages : 34
    Points : 22
    Points
    22
    Par défaut
    Effectivement j'avais pensé à modifier la date en augmentant la précision pour éviter les doublons.
    En tout cas pour moi, c'est résolu et je te remercie encore.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 22
    Dernier message: 07/07/2022, 20h13
  2. Réponses: 1
    Dernier message: 05/04/2019, 15h11
  3. Réponses: 7
    Dernier message: 05/04/2016, 17h15
  4. [AC-2010] comment sélectionner la dernière date sur plusieurs enregistrements
    Par mutlor dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 13/10/2013, 16h56
  5. date sur plusieurs colonnes
    Par courti01 dans le forum Excel
    Réponses: 2
    Dernier message: 09/01/2010, 19h34

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