Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 29/01/2011, 18h51   #1
Rédacteur
 
Avatar de Arnaud F.
 
Homme Arnaud Feltz
Développeur .NET
Inscription : août 2005
Messages : 5 204
Détails du profil
Informations personnelles :
Nom : Homme Arnaud Feltz
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Transports

Informations forums :
Inscription : août 2005
Messages : 5 204
Points : 6 113
Points : 6 113
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 :
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 :
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 :
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
Arnaud F. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 19h31   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 459
Points : 10 459
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Quel est votre SGBD ?
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 19h47   #3
Rédacteur
 
Avatar de Arnaud F.
 
Homme Arnaud Feltz
Développeur .NET
Inscription : août 2005
Messages : 5 204
Détails du profil
Informations personnelles :
Nom : Homme Arnaud Feltz
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Transports

Informations forums :
Inscription : août 2005
Messages : 5 204
Points : 6 113
Points : 6 113
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
Arnaud F. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 20h48   #4
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 443
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 443
Points : 7 528
Points : 7 528
Quelque chose comme ça :
Code :
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
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 22h37   #5
Rédacteur
 
Avatar de Arnaud F.
 
Homme Arnaud Feltz
Développeur .NET
Inscription : août 2005
Messages : 5 204
Détails du profil
Informations personnelles :
Nom : Homme Arnaud Feltz
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Développeur .NET
Secteur : Transports

Informations forums :
Inscription : août 2005
Messages : 5 204
Points : 6 113
Points : 6 113
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
Arnaud F. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2011, 21h18   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 950
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 950
Points : 17 769
Points : 17 769
Avec votre exemple incomplet :

Code :
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 :
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 :
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 :
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 :
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 :
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 :
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
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h15.


 
 
 
 
Partenaires

Hébergement Web