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 10/05/2011, 15h21   #1
Invité de passage
 
Inscription : décembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 5
Points : 1
Points : 1
Par défaut Sélectionner X lignes selon un autre champ

Bonjour,

J'ai à ma disposition SQL Server 2000 ou 2005 et j'ai une petite question SQL :

J'ai ce jeu de données :
Code :
1
2
3
4
5
6
7
8
9
10
Agence	Client
1	A
1	B
1	C
2	C
2	A
2	B
3	B
3	C
3	A
Je voudrais mettre dans une nouvelle table les 2 premiers clients de chaque agence, cela doit donner :
Code :
1
2
3
4
5
6
7
Agence	Client
1	A
1	B
2	C
2	A
3	B
3	C
Je me bats avec les fonctions TOP et GROUP BY mais je n'y arrive pas. Je sens une solution simple mais je n'arrive pas à mettre le doigt dessus.

Pourriez-vous m'aider ?

Merci beaucoup.
donabut est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 15h35   #2
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
Salut !

SQL Server dispose des fonction analytiques (plus sûr si c'est déjà à partir de 2000 cela dit) :
=> Cela te permet de numéroter tes lignes selon un ordre défini pour chaque partition (groupe)
Code :
1
2
3
4
5
6
7
 
SELECT agence, client
FROM (
    SELECT agence, client, row_number() over(partition BY agence ORDER BY client) rn
    FROM agence
) t
WHERE rn <= 2
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 15h39   #3
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 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
À partir de 2005 pour les fonctions de fenêtrage chez SQL-Server.

Par contre, il manque la donnée qui permet de définir "les deux premiers".
Dans l'exemple de pacmann, les données ont été triées par nom du client, mais dans l'exemple présenté ce n'est pas le cas.

Il manque donc la colonne qui permettra d'effectuer ce tri, une date par exemple.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 15h57   #4
Invité de passage
 
Inscription : décembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 5
Points : 1
Points : 1
Merci pour la rapidité de vos 2 réponses.

Pour Waldar, effectivement, pour simplifier l'exemple, j'ai trié les données comme je le voulais donc il n'y avait plus qu'à piocher dedans mais sur le principe, oui, il faut rajouter une 3ème colonne pour trier les clients.

Pour pacmann, mon analyseur de requêtes SQL ne reconnaît pas la fonction row_number : 'row_number' n'est pas un nom de fonction reconnu.
Je viens d'essayer avec la fonction IDENTITY(INT, 1, 1) mais cela numérote toute la table d'un coup sans faire de distinction par agence.

Merci à vous.
donabut est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 16h05   #5
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
Oui comme dit Waldar, la fonction n'est disponible qu'à partir de SQL Server 2005...

Tu peux faire un truc qui rame, du genre

Code :
1
2
3
4
5
6
7
 
SELECT a.agence, a.client
FROM agence a
WHERE 2 > (SELECT count(*) 
           FROM agence b 
           WHERE a.agence = b.agence 
             AND a.colonnetri > b.colonnetri)
A noter que si ta colonne de tri te donne des ex-aequo, ça va te ramener moins de lignes...
(tu peux alors changer la condition en
Code :
1
2
3
4
 
       WHERE a.agence = b.agence 
             AND a.client <> b.client
             AND a.colonnetri >= b.colonnetri
... mais là ça t'en ramènera potentiellement de trop en cas d'égalité)
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 16h14   #6
Invité de passage
 
Inscription : décembre 2008
Messages : 5
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 5
Points : 1
Points : 1
Tu es au TOP pacmann, ça marche du feu de dieu ! =D

Merci à vous pour la rapidité.
donabut est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 16h23   #7
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour

Pour ce type de requête, il vrai que la version 2005 apporte des améliorations non négligeables. Dans votre cas, un CROSS APPLY (disponible également depuis 2005) est tout indiqué :

Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
 
SELECT 
    a.agence,
    T.nom
FROM agence a
CROSS APPLY (
    SELECT TOP(2) 
        c.nom
    FROM Client c
    WHERE c.id_agence = a.id_agence
    ORDER BY Nom
)T

Avec un index sur Client(id_agence, nom), cela peut donner des résultats très satisfaisants !
aieeeuuuuu 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 11h21.


 
 
 
 
Partenaires

Hébergement Web