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 :

Comment afficher une liste de groupes avec le premier élément de chaque groupe ?


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Comment afficher une liste de groupes avec le premier élément de chaque groupe ?
    Bonjour !

    Je veux afficher la liste des groupes en affichant le nom du premier enfant inscrit sur base de la date d'inscription (et ensuite sur base de son ID, si deux enfants sont inscrits à la même date).

    voilà mes tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    T_GROUPE
    (
      ID_GROUPE INTEGER PRIMARY KEY NOT NULL,
      GROUPE_LIBELLE VARCHAR(50)
    )
     
    T_ENFANT
    (
      ID_ENFANT INTEGER PRIMARY KEY NOT NULL,
      NOM VARCHAR(50),
      PRENOM VARCHAR(50),
      ID_GROUPE INTEGER NOT NULL,
      DATE_INSCRIPTION DATE
    );
    Pour le moment, je fais une requête pour afficher la liste des groupes, et puis pour chaque groupe (boucle PHP), je refais une requête pour afficher le nom du premier enfant.

    Serait-il possible d'optimiser cela en faisant une seule requête ?

    Merci pour votre aide !

  2. #2
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 239
    Points : 313
    Points
    313
    Par défaut
    Bonjour,

    Que pensez-vous de ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT G.*, E.* 
    	FROM T_GROUPE G, T_ENFANT E
    	WHERE E.ID_GROUPE = E.ID_GROUPE
    	AND E.DATE_INSCRIPTION IN 
    		(SELECT MIN(E1.DATE_INSCRIPTION)
    		FROM T_ENFANT E1
    		WHERE E.ID_GROUPE = E1.ID_GROUPE)

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    J'en suis arrivé à la même requête que vous (si ce n'est que j'ai utilisé = à la place de IN), mais cela ne fonctionne pas si plusieurs enfants se sont inscrits à la même date.

    J'avais songé à utiliser un ORDER BY DATE_INSCRIPTION ASC, ID_ENFANT accompagné d'un LIMIT 1 mais je trouve pas où je peux utiliser ces critères.

    Je ne veux pas trop vite penser à me dire que c'est impossible, je jurerai que je brûle, mais le déclic ne se fait pas.

  4. #4
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Cherche pour chaque groupe le min de la concaténation (date + id)
    Du coup, tu feras la jointure sur ce truc là.

    Attention, il faut que la conversion de ton ID en chaîne ait une longueur constante :
    Il faut faire un pad de taille le log10 de ton ID jusqu'à le nombre de chiffres max estimé de ton ID (pour tu 32 bits, ça doit faire du 10 caractères)

    (Ensuite, tu utilises du substring pour redécouper ce min bizarre)

    Si t'y arrives pas je reviens

  5. #5
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    239
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 239
    Points : 313
    Points
    313
    Par défaut
    Ou sinon, sur le principe, mais c'est peut être simplifiable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT G.*, E.* 
    	FROM T_GROUPE G, T_ENFANT E
    	WHERE E.ID_GROUPE = E.ID_GROUPE
    	AND ID_ENFANT IN 
    		(SELECT 
    			FROM T_ENFANT E1
    			WHERE E.ID_GROUPE = E1.ID_GROUPE
    			AND E1.DATE_INSCRIPTION = 
    				(SELECT MIN(E2.DATE_INSCRIPTION)
    					FROM T_ENFANT E2
    					WHERE E.ID_GROUPE = E1.ID_GROUPE)
    			LIMIT 0, 1)

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 21
    Points : 43
    Points
    43
    Par défaut
    La requète précédente est incorrecte. Essayer plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT G.*, E.* 
    	FROM T_GROUPE G join T_ENFANT E on G.ID_GROUPE=E.ID_GROUPE
    	WHERE ID_ENFANT IN 
    		(SELECT 
    			FROM T_ENFANT E1
    			WHERE E.ID_GROUPE = E1.ID_GROUPE
    			ORDER BY E1.DATE_INSCRIPTION
    			LIMIT 0, 1)

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 899
    Points : 53 140
    Points
    53 140
    Billets dans le blog
    6
    Par défaut
    LIMIT n'existe pas en SQL, c'est une invention de MySQL !

    La solution en pur SQL, fait appel aux fonctions de fenêtrage de la norme SQL:1999 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT ID_GROUPE, GROUPE_LIBELLE, 
           ID_ENFANT, NOM, PRENOM, DATE_INSCRIPTION
    FROM   (SELECT ID_GROUPE, GROUPE_LIBELLE, 
                   ID_ENFANT, NOM, PRENOM, DATE_INSCRIPTION,
                   RANK() OVER(PARTITION BY ID_GROUPE ORDER BY ID_ENFANT) AS N
            FROM   T_GROUPE AS G
                   INNER JOIN T_ENFANT AS E
                         ON G.ID_GROUPE = E.ID_GROUPE) AS T
    WHERE   N = 1
    elle est évidemment beaucoup plus simple et plus performante !

    Sur les fonctions de fenêtrage : http://sqlpro.developpez.com/article...clause-window/

    A +

    A +

Discussions similaires

  1. Comment afficher une liste sur la même ligne avec tous les navigateurs
    Par Alexandrebox dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 25/07/2010, 03h05
  2. Réponses: 1
    Dernier message: 29/08/2007, 14h08
  3. Comment afficher une liste de liens ?
    Par Ekinoks dans le forum Struts 1
    Réponses: 2
    Dernier message: 11/07/2007, 09h24
  4. [MySQL] Afficher une liste de livres avec une rupture par auteur
    Par Ericx_25 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 12/03/2007, 22h02
  5. Comment initialiser une liste de composants avec une boucle ?
    Par EricSid dans le forum Composants VCL
    Réponses: 5
    Dernier message: 06/04/2005, 18h46

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