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 : 34
    Localisation : France

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

    Informations forums :
    Inscription : août 2005
    Messages : 5 183
    Points : 8 870
    Points
    8 870
    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 ?
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Consultant Teradata
    Inscrit en
    septembre 2008
    Messages
    8 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : septembre 2008
    Messages : 8 218
    Points : 17 141
    Points
    17 141
    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 : 34
    Localisation : France

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

    Informations forums :
    Inscription : août 2005
    Messages : 5 183
    Points : 8 870
    Points
    8 870
    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 ...
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    En instance de retraite
    Inscrit en
    mai 2002
    Messages
    8 886
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : En instance de retraite
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 8 886
    Points : 29 644
    Points
    29 644
    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
    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.

  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 : 34
    Localisation : France

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

    Informations forums :
    Inscription : août 2005
    Messages : 5 183
    Points : 8 870
    Points
    8 870
    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
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  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
    20 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : mai 2002
    Messages : 20 951
    Points : 49 773
    Points
    49 773
    Billets dans le blog
    1
    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 +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 03/08/2012, 16h03
  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, 16h41
  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, 07h11
  4. Valeur la plus présente
    Par kicao dans le forum Images
    Réponses: 15
    Dernier message: 14/01/2009, 16h40
  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, 04h31

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