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 :

Une requête - a priori - simple, mais qui s'avère difficile.


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut Une requête - a priori - simple, mais qui s'avère difficile.
    Bonjour à tous,

    Je suis confronté à un problème qui semble simple, de prime abord. Seulement, après réflexion, il s'avère plus difficile qu'il n'y parait. Je sèche...

    Voici le problème :

    Je dispose d'une table qui présente trois colonnes :
    • La colonne "idex" : Une clé primaire, auto incrémentée.
    • La colonne "clock" : Une date (de type DATETIME).
    • La colonne "value" : Un entier non signé.


    Je désire sélectionner les plages temporelles (déterminées par un couple de valeurs de la colonne "clock") sur lesquelles les valeurs de la colonne "value" sont croissantes.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    idex   clock                 value
    1      2010-01-01 00:00:00   1
    2      2010-01-01 00:00:01   1
    3      2010-01-01 00:00:02   1
    4      2010-01-01 00:00:02   10
    5      2010-01-01 00:00:02   1
    6      2010-01-01 00:00:03   2
    7      2010-01-01 00:00:04   3
    8      2010-01-01 00:00:05   4
    9      2010-01-01 00:00:06   1
    Résultat :

    • Première plage : [de 2010-01-01 00:00:00 (id=1) à 2010-01-01 00:00:02 (id=4)]
    • Deuxième plage : [de 2010-01-01 00:00:02 (id=5) à 2010-01-01 00:00:05 (id=8)]
    • Troisième plage : [de 2010-01-01 00:00:06 (id=9) à 2010-01-01 00:00:06 (id=9)]


    Remarque : Je ne suis pas certain que l'on puisse effectuer cette opération en utilisant du SQL uniquement.

    Si vous pouvez me mettre sur la piste, je vous en serais reconnaissant!

    Note: Je travaille avec MySql.

    Merci,

    Denis

  2. #2
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Saluton,
    value étant un mot réservé de MySQL dans ma proposition de requête je l'ai remplacé par valoro (sa traduction en espéranto)
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT t1.clock, t1.valoro,
           t3.clock, t3.valoro
    FROM latable t1
    INNER JOIN (SELECT t2.clock, t2.valoro
                FROM latable t2
                WHERE t2.clock > t1.clock
                  AND t2.valoro > t1.valoro
                ORDER BY t2.clock ASC
                LIMIT 1) t3
    Seule inquiétude, je ne sais plus si MySQL accepte les clauses ORDER BY et LIMIT dans les sous-requêtes.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Saluton,
    value étant un mot réservé de MySQL dans ma proposition de requête je l'ai remplacé par valoro (sa traduction en espéranto)
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT t1.clock, t1.valoro,
           t3.clock, t3.valoro
    FROM latable t1
    INNER JOIN (SELECT t2.clock, t2.valoro
                FROM latable t2
                WHERE t2.clock > t1.clock
                  AND t2.valoro > t1.valoro
                ORDER BY t2.clock ASC
                LIMIT 1) t3
    Seule inquiétude, je ne sais plus si MySQL accepte les clauses ORDER BY et LIMIT dans les sous-requêtes.
    Salut Maljuna Kris,

    Je te remercie pour cette réponse. J'avoue que je ne comprends pas cette requête (j'ai du mal avec les jointures "sur une même table").

    J'ai modifié mon jeu de test afin de l'adapter à la notation que tu utilises.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE  TABLE IF NOT EXISTS `ex` (
      `idex` INT NOT NULL AUTO_INCREMENT ,
      `clock` DATETIME NULL ,
      `valoro` INT NULL ,
      PRIMARY KEY (`idex`) )
    ENGINE = InnoDB;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    insert into ex set clock='2010-01-01 00:00:01', valoro=1;
    insert into ex set clock='2010-01-01 00:00:02', valoro=2;
    insert into ex set clock='2010-01-01 00:00:02', valoro=2;
    insert into ex set clock='2010-01-01 00:00:03', valoro=2;
    insert into ex set clock='2010-01-01 00:00:04', valoro=10;
    insert into ex set clock='2010-01-01 00:00:04', valoro=1;
    insert into ex set clock='2010-01-01 00:00:05', valoro=2;
    insert into ex set clock='2010-01-01 00:00:06', valoro=3;
    insert into ex set clock='2010-01-01 00:00:07', valoro=4;
    insert into ex set clock='2010-01-01 00:00:07', valoro=1;

    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
    mysql> select * from ex;
    +------+---------------------+--------+
    | idex | clock               | valoro |
    +------+---------------------+--------+
    |    1 | 2010-01-01 00:00:01 |      1 |
    |    2 | 2010-01-01 00:00:02 |      2 |
    |    3 | 2010-01-01 00:00:02 |      2 |
    |    4 | 2010-01-01 00:00:03 |      2 |
    |    5 | 2010-01-01 00:00:04 |     10 |
    |    6 | 2010-01-01 00:00:04 |      1 |
    |    7 | 2010-01-01 00:00:05 |      2 |
    |    8 | 2010-01-01 00:00:06 |      3 |
    |    9 | 2010-01-01 00:00:07 |      4 |
    |   10 | 2010-01-01 00:00:07 |      1 |
    +------+---------------------+--------+
    10 rows in set (0.00 sec)

    Avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT t1.clock, t1.valoro,
           t3.clock, t3.valoro
    FROM ex AS t1
    INNER JOIN (SELECT t2.clock, t2.valoro
                FROM ex AS t2, t1
                WHERE t2.clock > t1.clock
                  AND t2.valoro > t1.valoro
                ORDER BY t2.clock ASC
                LIMIT 1) t3;
    Note : J'ai un peu modifié la requête pour coller avec la syntaxe de MySql.

    La requête ne fonctionne pas (erreur de "structure"). Je suppose qu'elle doit être écrite pour une autre base que MySql. Cela me rappelle une syntaxe utilisée par des DBA Oracle.

    J'avoue que mon niveau en SQL est vraiment trop faible. Je ne vois pas la "logique" de cette jointure.

    Je vais me pencher dessus plus en détail demain.

    Peut-être est-il possible de créer des tables temporaires? Puis on pourrait faire des jointures sur ces tables? (ce n'est qu'une idée de "novice" en SQL).

    Merci encore,

    A+

  4. #4
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Apparemment, ce qui gêne MySQL dans ma proposition c'est qu'il ne parvient pas, dans la sous-requête, à faire la corrélation avec la requête principale.
    Je dois être bien fatigué ce soir car je ne comprends pas pourquoi.
    Probablement que demain j'en serais tout , mais là je décroche.
    Dans la sous-requête t1.clock n'est pas reconnu
    #1054 - Unknown column 't1.clock' in 'where clause'
    D'où ta louable, mais vaine, tentative d'ajouter une hypothétique table t1 dans la clause FROM de la sous-requête
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  5. #5
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Bon, après un petit verre de resolí, j'ai un premier flash :
    Ma jointure INNER JOIN n'a pas de clause ON, or les conditions de cette clause seraient celles de la clause WHERE de la sous-requête, mais celles-ci n'auraient de sens que couplées avec le ORDER BY et le LIMIT.
    Donc ma proposition est du grand n'importe quoi;
    Désolé
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  6. #6
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Finalement je n'étais pas si loin que cela de la solution :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT DISTINCT t1.clock, t1.valoro,
           t2.clock, t2.valoro
    FROM ex t1, ex t2
    WHERE t2.idex= (SELECT t3.idex
                FROM ex t3
                WHERE t3.clock > t1.clock
                  AND t3.valoro > t1.valoro
                ORDER BY t3.clock ASC
                LIMIT 1)
    ORDER BY t1.clock
    résultat
    2010-01-01 00:00:01 1 2010-01-01 00:00:02 2
    2010-01-01 00:00:02 2 2010-01-01 00:00:04 10
    2010-01-01 00:00:03 2 2010-01-01 00:00:04 10
    2010-01-01 00:00:04 1 2010-01-01 00:00:05 2
    2010-01-01 00:00:05 2 2010-01-01 00:00:06 3
    2010-01-01 00:00:06 3 2010-01-01 00:00:07 4
    Avec le jeu d'essai que tu nous a fourni.
    Bon, vu comment la corrélation est réputée gourmande en MySQL les colonnes clock et valoro ont intérêt à être indexées, surtout si la table est volumineuse.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  7. #7
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par Maljuna Kris Voir le message
    Finalement je n'étais pas si loin que cela de la solution :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT DISTINCT t1.clock, t1.valoro,
           t2.clock, t2.valoro
    FROM ex t1, ex t2
    WHERE t2.idex= (SELECT t3.idex
                FROM ex t3
                WHERE t3.clock > t1.clock
                  AND t3.valoro > t1.valoro
                ORDER BY t3.clock ASC
                LIMIT 1)
    ORDER BY t1.clock
    résultatAvec le jeu d'essai que tu nous a fourni.
    Bon, vu comment la corrélation est réputée gourmande en MySQL les colonnes clock et valoro ont intérêt à être indexées, surtout si la table est volumineuse.
    Bonjour Maljuna Kris,

    Vraiment, c'est super! Je te remercie mille fois pour ton aide! J'étais en train de partir dans un vrai délire : Je cherchais à appliquer des méthodes de développeurs avec des requêtes SQL (Là, on ne s'en sort pas!).

    J'avoue que je ne comprends pas tout. Je vais me pencher en détail sur la requête.

    Question: Existe-t-il cite Internet qui collecte des requêtes SQL, et qui les classe par thèmes? Par exemple, pour ce qui est du code : http://rosettacode.org/wiki/Main_Page

    Si ce site existe, alors je vais m'empresser de déposer cette requête, car elle est vraiment bien! Elle pourrait être réutilisée dans un grand nombre de situations.

    Merci encore Maljuna Kris,

    Denis

Discussions similaires

  1. Test d'une expression régulière simple mais qui ne marche pas
    Par bernidupont dans le forum Général VBA
    Réponses: 6
    Dernier message: 07/05/2015, 11h38
  2. Difficulté pour une requête a priori simple
    Par Evocatii dans le forum Langage SQL
    Réponses: 2
    Dernier message: 03/08/2011, 21h19
  3. Requête simple mais qui ne marche pas
    Par larbiDida dans le forum Requêtes
    Réponses: 4
    Dernier message: 31/03/2011, 16h56
  4. Problème a priori simple mais qui rend fou
    Par Fav' da Boy dans le forum ActionScript 1 & ActionScript 2
    Réponses: 0
    Dernier message: 21/09/2009, 18h41
  5. Requête SQL qui a l'air simple mais qui est musclée !
    Par tamiii dans le forum Langage SQL
    Réponses: 5
    Dernier message: 04/07/2008, 16h51

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