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

Langage SQL Discussion :

Requête SQL pour boucler


Sujet :

Langage SQL

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut Requête SQL pour boucler
    Bonjour,

    Voici des données non exhaustives, la requête doit pouvoir marcher sur X nombre de lignes ayant le même IDK

    CD ; PERS_; NORN05; IDKI; IDCT; EA; CDC; IDI ; IDQ ;VAVA; IY; DDIQR ; DDIQ ; DDIQ03; PERS ; NOC;
    459; 000004383 ; 642016703 ; 00087303; 007152392; 2; 49; SR000055; SR000055; UX3 ; 1; 31/10/2014; 31/10/2014; 18/11/2014 ; 901537746 ; 7716523;
    459; 000004383 ; 642016703 ; 00087303; 007165792; 2; 49; SR000055; SR000055; DT2; 1; 31/10/2014; 31/10/2014; 18/11/2014 ; 901537746 ; 7716557;


    Je peux avoir X NOC rattachés à 1 IDKI.

    L'idée c'est de pouvoir récupérer la ligne où la date est la plus antérieure pour DDIQR pour le même IDKI en parcourant l'ensemble des NOC ...

    J'ai tenté de doubler ma table 1 et table 2 pour boucler mais je n'y parviens pas :/

    (J'aimerais le faire sans while) Est-ce possible ?

    Comment faire ? Merci d'avance.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 143
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    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 143
    Par défaut
    Cette question est posée très régulièrement sur le forum.
    Le modèle de la requête est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT  *
    FROM    matable tb1
    WHERE   EXISTS
            (   SELECT  1
                FROM    matable tb2
                WHERE   tb1.clef = tb2.clef
                HAVING  tb1.date = MAX(tb2.date) 
            )
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    j'ai donc très mal recherché ... merci pour ton aide... j'essaye d'appliquer le template

    PS : super ça marche merci, pour le coup comment faire pour ne récupérer qu'une ligne si toutes les dates sont identiques ?

    Concrètement dans l'exemple donné, j'ai 2 fois la même date max et les deux lignes sont affichées, comment faire pour faire en sorte qu'une seule ligne remonte dans ce cas spécifique ? J'ai tenté un TOP mais sans espoir ... le SQL aura ma peau :'(

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Bonjour, me revoilou !

    La requête marche à ceci près que je suis limité en ressources CPU et que je ne peux rien y faire ... la table fait quelque chose comme 33 000 000 de lignes :p ... il faut donc que j'optimise ...

    Comment puis-je modifier la requête pour récupérer les informations par rapport à la date maximum pour chaque ID distinct ?

    exemple :

    ID ; DATE ; VALEUR
    12 ; 12/10/2013 ; 12
    12 ; 12/11/2014 ; DD
    12 ; 12/12/2014 ; XX
    13 ; 14/08/2012 ; 01
    13 ; 14/12/2013 ; 01
    14 ; 12/10/2011 ; 05
    15 ; 11/10/2010 ; 05

    L'idée, c'est de pouvoir récupérer les lignes pour lesquelles les dates sont au max (Max différents ... ) par distinct d'ID ... je ne vois pas trop côté logique SQL ... pour tester le max sur chaque IDCR00, ce max étant différent à chaque fois :/
    12 ; 12/12/2014 ; XX
    13 ; 14/12/2013 ; 01
    14 ; 12/10/2011 ; 05
    15 ; 11/10/2010 ; 05

  5. #5
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Question classique en effet mais j'ai une autre approche...

    1) Quelle est la date maxi pour chaque ID ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT ID, MAX(`DATE`) AS date_max
    FROM la_table
    GROUP BY ID
    2) On récupère toutes les infos de la ligne correspondant à cette date max de chaque ID :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT t.ID, t.`DATE`, t.VALEUR
    FROM la_table t
    INNER JOIN
    (
    	SELECT ID, MAX(`DATE`) AS date_max
    	FROM la_table
    	GROUP BY ID
    ) tmp 
    	ON tmp.ID = t.ID
    	AND tmp.date_max = t.`DATE`
    Remarque : 'DATE' est un mauvais nom de colonne car c'est un mot réservé du langage SQL. D'où l'utilisation des apostrophes inversées de MySQL pour entourer le nom de la colonne DATE dans ma requête. Mais peut-être n'utilisez-vous pas MySQL ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Sur une telle volumétrie, il faut d'abord s'assurer que les index adéquats sont posés.

    Vous pouvez essayer cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    WITH CTE AS (
        SELECT ID,DATE, VALEUR, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY DAET DESC) AS Rn
        FROM LaTable
    )
    SELECT  ID,DATE, VALEUR
    FROM CTE
    WHERE Rn = 1

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Merci pour vos réponses

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT t.ID, t.`DATE`, t.VALEUR
    FROM la_table t
    INNER JOIN
    (
    	SELECT ID, MAX(`DATE`) AS date_max
    	FROM la_table
    	GROUP BY ID
    ) tmp 
    	ON tmp.ID = t.ID
    	AND tmp.date_max = t.`DATE`
    Qu'elle serait la différence avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      SELECT  *
    FROM   TABLE tb1
    WHERE   EXISTS
            (   SELECT  1
                FROM    TABLE tb2
                WHERE   tb1.ID= tb2.ID
                HAVING  tb1.DATE= MAX(tb2.DATE)
            )
    J'ai renommé le champs DATE pour que ce soit plus clair mais ce n'est effectivement pas le nom du champ en BDD
    En tous les cas merci !

  8. #8
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    En tout cas je suis choqué par la présence du HAVING sans GROUP BY !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    effectivement ... le souci étant que j'essaye de me créer des compteurs en fonction des valeurs pour les regrouper ... mais ça ne passe pas avec les group by

    Je vais extraire et retraiter derrière

    Je voulais surtout savoir s'il y a un optimal entre ces deux requêtes ou si ça revenait au même et sinon, pourquoi ?

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    En tout cas je suis choqué par la présence du HAVING sans GROUP BY !
    Tant que la requête ne renvoie qu'une ligne, ce n'est pas choquant.

    Citation Envoyé par Nikimizi Voir le message
    Qu'elle serait la différence avec...
    Dans l'esprit, la première requête va d'abord calculer tous les max(date) par Id puis faire la jointure.
    La seconde requête va lire une ligne de la table, va aller tester si la date correspond au max(date) et garder ou supprimer la ligne en fonction.

    Le premier est beaucoup plus optimal pour traiter une volumétrie importante, le second plus optimal pour traiter quelques id à condition d'avoir le bon index sur (id, date).
    En fonction du SGBD et de la qualité de l'optimiseur, les interprétations peuvent être très différentes : vérifiez les plans d'exécution.

  11. #11
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    effectivement ... le soucis étant que j'essaye de me créer des compteurs en fonction des valeurs pour les regrouper ... mais ca ne passe pas avec les group by
    Pourriez-vous expliquer plus en détail votre besoin ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Avril 2009
    Messages : 153
    Par défaut
    Voici le détail :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT VALEUR, COUNT(CONTRAT) FROM (
    SELECT A.*, B.* FROM (
            SELECT ID CONTRAT, MAX(DATE) AS DATE_MAX
            FROM table
            GROUP BY ID
    ) AS A
    LEFT JOIN (
             SELECT ID, DATE, VALEUR, X1, X2, X3
             FROM table
    ) AS B
    ON (A.CONTRAT = B.ID AND A.DATE_MAX = B.DATE)
    ) AS C
    GROUP BY VALEUR
    Le but étant de récupérer la dernière ligne pour chaque date max, avec les données qui m'intéressent et de les grouper par valeur.

    Merci pour vos aides respectives

  13. #13
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Je remets votre requête en forme pour qu'elle soit plus lisible :
    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
    SELECT VALEUR, COUNT(CONTRAT) 
    FROM 
    (
    	SELECT A.*, B.* 
    	FROM 
    	(
    		SELECT ID CONTRAT, MAX(DATE) AS DATE_MAX
    		FROM table
    		GROUP BY ID
    	) AS A
    	LEFT JOIN 
    	(
    		SELECT ID, DATE, VALEUR, X1, X2, X3
    		FROM table
    	) AS B
    		ON A.CONTRAT = B.ID
    		AND A.DATE_MAX = B.DATE
    ) AS C
    GROUP BY VALEUR
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT ID, DATE, VALEUR, X1, X2, X3
    Pourquoi récupérer toutes ces colonnes puisque vous n'avez besoin que de ID, de DATE et de VALEUR ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

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

Discussions similaires

  1. Requête SQL pour insérer une donnée BINAIRE ?
    Par Najdar dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 22/05/2006, 10h21
  2. Requêtes SQL pour les Dates et numériques
    Par Ramage03 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/03/2006, 17h26
  3. Requête SQL pour afficher un tri
    Par arnaud_verlaine dans le forum Langage SQL
    Réponses: 4
    Dernier message: 16/11/2005, 15h27
  4. problème de requète SQL pour formulaire
    Par en_stage dans le forum Requêtes et SQL.
    Réponses: 15
    Dernier message: 21/06/2005, 12h21
  5. Requêtes SQL pour access
    Par cciocc dans le forum Langage SQL
    Réponses: 5
    Dernier message: 25/04/2005, 08h45

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