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 :

Sélection de données à partir de la valeur la plus présente.


Sujet :

Langage SQL

  1. #1
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Points : 8 873
    Points
    8 873
    Par défaut Sélection de données à partir de la valeur la plus présente.
    Bonjour,

    j'ai un gros doute, trou sur la manière de récupérer les informations.

    Prenons la table suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE gaulois
    (
        gauno int not null,
        vilno int not null
    )
    La requête suivante me retourne le nombre de gaulois par village :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT vilno, COUNT(*)
    FROM gaulois
    GROUP BY vilno
    Mais si maintenant je souhaite récupérer la liste des gaulois habitant le village le plus peuplé, je pensais pouvoir écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT gaulois.gauno, gaulois.vilno
    FROM gaulois,
    (
    SELECT vilno, COUNT(*) as "nb_gaulois"
    FROM gaulois
    GROUP BY vilno
    ) g
    WHERE gaulois.vilno = g.vilno
    HAVING nb_gaulois = MIN(nb_gaulois)
    Mais évidemment, ça ne fonctionne pas, quelle est la meilleure de procéder ?

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Quel est votre SGBD ?

  3. #3
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Points : 8 873
    Points
    8 873
    Par défaut
    J'aurai tendance a dire, peut importe le SGBD, un truc cross-DB quoi...

    Y a une solution "simple" en utilisant un LIMIT MySQL mais si je peux éviter

    La requête paraît si simple quand on la dit, mais quand on voit la logique qu'il faut derrière ou la liste de sous-requêtes nécessaires pour y arriver, ça fait juste peur ...

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    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 108
    Points : 28 419
    Points
    28 419
    Par défaut
    Quelque chose comme ça :
    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  gaulois.gauno
        ,   gaulois.vilno
    FROM    gaulois
        INNER JOIN
            (   SELECT  vilno
                    ,   COUNT(*) AS nb_gaulois
                FROM    gaulois
                GROUP BY vilno
            )   ville
            ON  gaulois.vilno = ville.vilno
        INNER JOIN
            (   SELECT  MAX(nb_gaulois) AS max_nb
                FROM    (   SELECT  COUNT(*) AS nb_gaulois
                            FROM    gaulois
                            GROUP BY vilno
                        )
            )   max_ville
            ON  ville.nb_gaulois = max_ville.max_nb
    ;
    On peut certainement faire mieux en utilisant les fonctions analytiques de regroupement, mais tu n'as pas dit si ton SGBD les acceptait

  5. #5
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Points : 8 873
    Points
    8 873
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    On peut certainement faire mieux en utilisant les fonctions analytiques de regroupement, mais tu n'as pas dit si ton SGBD les acceptait
    Késako les fonctions de regroupement?

    Pour la requête, elle fonctionne, merci bien

  6. #6
    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
    Avec votre exemple incomplet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE gaulois
    (
        gauno int NOT NULL,
        vilno int NOT NULL
    );
     
    INSERT INTO gaulois 
    VALUES (1, 1), (2, 1), (3, 1), 
           (4, 2), (5, 2), (6, 2), 
           (7, 3), (8, 3), 
           (9, 4);
    Voici 6 solutions différentes, parfaitement normalisées (SQL:1999) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    -- première solution, avec imbrication d'agrégats :
    SELECT vilno
    FROM   gaulois
    GROUP  BY vilno
    HAVING COUNT(*) = (SELECT MAX(NOMBRE)
                       FROM (SELECT COUNT(*) AS NOMBRE
                             FROM   gaulois
                             GROUP  BY vilno) AS T);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- deuxième solution (avec CTE)
    WITH T AS
    (SELECT COUNT(*) AS NOMBRE, vilno
     FROM   gaulois
     GROUP  BY vilno)
    SELECT vilno
    FROM   T
    WHERE  NOMBRE = (SELECT MAX(NOMBRE)
                     FROM   T);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    -- troisième solution avec ALL :
    SELECT vilno
    FROM   gaulois
    GROUP  BY vilno
    HAVING COUNT(*) >= ALL(SELECT COUNT(*) AS NOMBRE
                           FROM   gaulois
                           GROUP  BY vilno);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- quatrième solution avec ALL et CTE :
    WITH T AS
    (SELECT COUNT(*) AS NOMBRE, vilno
     FROM   gaulois
     GROUP  BY vilno)
    SELECT vilno
    FROM   T
    WHERE  NOMBRE>= ALL(SELECT NOMBRE
                        FROM   T);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -- cinquième solution (avec EXISTS)
    WITH T AS
    (SELECT COUNT(*) AS NOMBRE, vilno
     FROM   gaulois
     GROUP  BY vilno)
    SELECT vilno
    FROM   T AS T1
    WHERE  EXISTS (SELECT NULL
                   FROM   T AS T2
                   HAVING T1.NOMBRE = MAX(T2.NOMBRE));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    -- sixième solution avec RANK :
    WITH T AS
    (SELECT vilno, RANK() OVER(ORDER BY COUNT(*) DESC) AS N
     FROM   gaulois
     GROUP  BY vilno)
    SELECT vilno
    FROM   T
    WHERE  N = 1;
    Et pour un cours sur SQL, mon livre,, comme mon site web peuvent vous y aider !

    A +

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 03/08/2012, 15h03
  2. Sélection d'observations à partir d'une valeur seuil
    Par patril dans le forum SAS Base
    Réponses: 8
    Dernier message: 01/08/2011, 15h41
  3. [WD12] Extraire valeur la plus présente dans une série de nombre
    Par le pingouin fou dans le forum WinDev
    Réponses: 7
    Dernier message: 13/07/2011, 06h11
  4. Valeur la plus présente
    Par kicao dans le forum Images
    Réponses: 15
    Dernier message: 14/01/2009, 15h40
  5. Filtre de valeurs dans la base de données à partir d'excel
    Par xtian_Québec dans le forum VBA Access
    Réponses: 1
    Dernier message: 23/12/2007, 03h31

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