Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Access > Requêtes et SQL.
Requêtes et SQL. Tout ce qui concerne vos questions sur les requêtes et le SQL sous Access se trouve ici.
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/03/2011, 15h57   #1
Membre du Club
 
Avatar de windmastr26
 
Homme
Développeur informatique
Inscription : juillet 2009
Messages : 176
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juillet 2009
Messages : 176
Points : 48
Points : 48
Par défaut [Jointures] Trier une jointure

Salut à tous,

J'ai un soucis d'optimisation de requête.

J'ai 3 tables :

Code :
1
2
3
Article (Code, ...)
LigneCdeFournisseur (CodeArticle, CodeDocument, DateDocument, ...)
EnteteCdeFournisseur (Code, Date, Delai, ...)
Le principe, comme vous l'aurez sûrement compris, c'est qu'une commande (identifiée par un Code) est composée de lignes (identifiées par le code de l'article qu'elle représente et le code du document - commande - à laquelle elle appartient).

Ce que je souhaite, c'est afficher la liste des articles avec, pour chacun d'eux, le délai de livraison (Delai) correspondant à la commande la plus ancienne (Date).

Pour le moment, la seule façon d'aboutir à ce résultat est la requête suivante :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT
  Article.Code,
  Article.CodeBarre,
  Article.Nom,
  Article.Emplacement,
  Article.QteCdt,
  Article.Fr,
  Article.Prixpiece,
  Article.StockMinGen,
  Article.StockMaxGen,
  Article.StockPhyGen,
  Article.ReliquatFseur,
  (SELECT TOP 1 LigneCdeFournisseur.DateDocument & ' (' & EnteteCdeFournisseur.Delai & ')' from EnteteCdeFournisseur, LigneCdeFournisseur
   Where EnteteCdeFournisseur.Code=LigneCdeFournisseur.CodeDocument And LigneCdeFournisseur.CodeArticle=Article.Code And LigneCdeFournisseur.LigneSoldee=0
   Order by DateDocument desc) as Delai
FROM Article
Mais le temps d'exécution de la requête est long (certainement à cause de la sous requête).

J'aimerai donc utiliser des jointures plutôt qu'une sous requête, mais je ne sais pas comment adapter cela...

Quelqu'un a une idée ?

Merci
windmastr26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 16h06   #2
Expert Confirmé Sénior
 
Avatar de f-leb
 
Homme Fabien
Enseignant
Inscription : janvier 2009
Messages : 2 410
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 41
Localisation : France, Sarthe (Pays de la Loire)

Informations professionnelles :
Activité : Enseignant

Informations forums :
Inscription : janvier 2009
Messages : 2 410
Points : 4 439
Points : 4 439
bonjour windmastr26,

est-ce que c'est mieux avec:
Code sql :
1
2
3
4
5
6
7
8
9
 
..., (SELECT TOP 1 lignecdefournisseur.datedocument & ' (' & 
                     entetecdefournisseur.delai & ')' 
        FROM   entetecdefournisseur INNER JOIN lignecdefournisseur 
        ON   entetecdefournisseur.code=lignecdefournisseur.codedocument 
        WHERE  lignecdefournisseur.codearticle = article.code 
               AND lignecdefournisseur.lignesoldee = 0 
        ORDER  BY datedocument DESC) AS delai
FROM ...
f-leb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 16h31   #3
Membre du Club
 
Avatar de windmastr26
 
Homme
Développeur informatique
Inscription : juillet 2009
Messages : 176
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juillet 2009
Messages : 176
Points : 48
Points : 48
Hélas non, l'exécution n'est pas plus rapide... Je pense que c'est la sous requête qui alourdi considérablement le tout. Mais dans ce cas présent comment s'en passer ,
windmastr26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 16h55   #4
Expert Confirmé Sénior
 
Avatar de f-leb
 
Homme Fabien
Enseignant
Inscription : janvier 2009
Messages : 2 410
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 41
Localisation : France, Sarthe (Pays de la Loire)

Informations professionnelles :
Activité : Enseignant

Informations forums :
Inscription : janvier 2009
Messages : 2 410
Points : 4 439
Points : 4 439
je m'en doutais un peu.

On essaye avec une sous-requête enregistrée nommée SR:

ajouter la table LigneCdeFournisseur, faire un groupement sur codearticle et une opération Min sur DateDocument, avec un critère LigneSoldee=0.

la sous-requête SR renvoit la DateDocument la plus ancienne par codearticle dans tes lignes de commande.

Puis la requête principale avec les jointures:
LigneCdeFournisseur=====SR (jointure double sur les codes et les dates)

compléter avec les jointures LigneCdeFournisseur-----Article puis LigneCdFournisseur-----EnteteCdeFournisseur

faire glisser les champs souhaités et ça devrait aller si j'ai rien oublié
f-leb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 17h25   #5
Membre du Club
 
Avatar de windmastr26
 
Homme
Développeur informatique
Inscription : juillet 2009
Messages : 176
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juillet 2009
Messages : 176
Points : 48
Points : 48
Une sous-requête enregistrée c'est une requête que je dois au préalable créer sous Access ?

Le problème c'est que l'application qui exécute la requête n'a que des droits de lecture sur la base Access (et oui ! Tant qu'à faire compliqué...).
windmastr26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 17h55   #6
Expert Confirmé Sénior
 
Avatar de f-leb
 
Homme Fabien
Enseignant
Inscription : janvier 2009
Messages : 2 410
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 41
Localisation : France, Sarthe (Pays de la Loire)

Informations professionnelles :
Activité : Enseignant

Informations forums :
Inscription : janvier 2009
Messages : 2 410
Points : 4 439
Points : 4 439
Arghhh ! Tu veux dire qu’il faut rédiger la requête avec du gros SQL bien dégueu#@*&

Code sql :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SELECT a.code,
       a.codebarre,
       a.nom,
       a.emplacement,
       a.qtecdt,
       a.fr,
       a.prixpiece,
       a.stockmingen,
       a.stockmaxgen,
       a.stockphygen,
       a.reliquatfseur,
       lc.datedocument & ' (' & e.delai & ')' AS ledelai
FROM   ((article a
         INNER JOIN lignecdefournisseur lc
           ON a.code = lc.codearticle)
        INNER JOIN entetecdefournisseur e
          ON lc.codedocument = e.code)
       INNER JOIN (SELECT codearticle,
                          MIN(datedocument) AS mindedatedocument
                   FROM   lignecdefournisseur
                   WHERE  lignesoldee = 0
                   GROUP  BY codearticle) sr
         ON lc.codearticle = sr.codearticle
            AND lc.datedocument = sr.mindedatedocument;

Bon, je suis sûr de rien là…et une aspro pour f-leb
f-leb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 19h59   #7
Modérateur
 
Avatar de Chtulus
 
Homme Cédric
Cherche à comprendre
Inscription : avril 2008
Messages : 2 263
Détails du profil
Informations personnelles :
Nom : Homme Cédric
Âge : 32
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Cherche à comprendre

Informations forums :
Inscription : avril 2008
Messages : 2 263
Points : 4 421
Points : 4 421
Envoyer un message via MSN à Chtulus Envoyer un message via Skype™ à Chtulus
Citation:
Envoyé par f-leb Voir le message
Arghhh ! Tu veux dire qu’il faut rédiger la requête avec du gros SQL bien dégueu#@*&
Non mais dis donc
__________________
- De quelque manière qu'on s'y prenne on s'y prend toujours mal -
-Sigmund Freud-

Les meilleurs cours, tutoriels et Docs sur les SGBD et le SQL
Tous les cours Office

Chtulus est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 21h37   #8
Rédacteur/Modérateur
 
Avatar de User
 
Homme Denis
Développeur informatique
Inscription : août 2004
Messages : 3 205
Détails du profil
Informations personnelles :
Nom : Homme Denis
Âge : 42
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2004
Messages : 3 205
Points : 5 258
Points : 5 258
Citation:
Envoyé par f-leb Voir le message
Arghhh ! Tu veux dire qu’il faut rédiger la requête avec du gros SQL bien dégueu#@*&
D'un autre côté ces smileys ils sont là pour être utilisé

Allez windmastr26 tu es toujours le bienvenu parmi nous
__________________
Merci de ne pas poster sur mon profil pour des problèmes techniques. Pour celà vous pouvez utiliser le forum ou m'envoyer un mp.

Bon développement !


Mes tutoriels et contributions sur ma page perso:
Ma page personnelle
User est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 09h01   #9
Membre du Club
 
Avatar de windmastr26
 
Homme
Développeur informatique
Inscription : juillet 2009
Messages : 176
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juillet 2009
Messages : 176
Points : 48
Points : 48
Quel vocabulaire !!

Coté requête il ne me donne que les articles ayant fait l'objet d'une commande lol. Donc si l'article n'est pas en cours de commande il n'apparait pas.

Mais cette requête me donne d'autres idées que je vais essayer de tester. Je mettrais la requête finale si jamais je parviens à trouver.

Un grand merci en tout cas
windmastr26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 11h42   #10
Expert Confirmé Sénior
 
Avatar de f-leb
 
Homme Fabien
Enseignant
Inscription : janvier 2009
Messages : 2 410
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 41
Localisation : France, Sarthe (Pays de la Loire)

Informations professionnelles :
Activité : Enseignant

Informations forums :
Inscription : janvier 2009
Messages : 2 410
Points : 4 439
Points : 4 439
Citation:
Envoyé par windmastr26 Voir le message
Quel vocabulaire !!
C’est vrai que SELECT, INNER JOIN, GROUP BY et tout ça c’est vraiment très sale…

Par contre, j’aime bien m’y vautrer quand même… grouik grouiiiiiik

Citation:
Envoyé par windmastr26 Voir le message
Donc si l'article n'est pas en cours de commande il n'apparait pas.
Je rajoute un étage à la fusée : Article LEFT JOIN le reste…

Code sql :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
SELECT article.code,
       article.codebarre,
       article.nom,
       article.emplacement,
       article.qtecdt,
       article.fr,
       article.prixpiece,
       article.stockmingen,
       article.stockmaxgen,
       article.stockphygen,
       article.reliquatfseur,
       temp.datedocument & ' (' & temp.delai & ')' AS delai
FROM   article
       LEFT JOIN (SELECT a.code,
                         lc.datedocument,
                         e.delai
                  FROM   ((article a
                           INNER JOIN lignecdefournisseur lc
                             ON a.code = lc.codearticle)
                          INNER JOIN entetecdefournisseur e
                            ON lc.codedocument = e.code)
                         INNER JOIN (SELECT codearticle,
                                            MIN(datedocument) AS
                                            mindedatedocument
                                     FROM   lignecdefournisseur
                                     WHERE  lignesoldee = 0
                                     GROUP  BY codearticle) sr
                           ON lc.codearticle = sr.codearticle
                              AND lc.datedocument = sr.mindedatedocument) temp
         ON article.code = temp.code;
f-leb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 11h54   #11
Membre du Club
 
Avatar de windmastr26
 
Homme
Développeur informatique
Inscription : juillet 2009
Messages : 176
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juillet 2009
Messages : 176
Points : 48
Points : 48
Pas encore ça non. Certains articles ont des commandes en court mais n'apparaissent pourtant pas.

Mais je vais me replonger dedans avec les morceaux de requête que tu as rajouté. Je finirai bien par trouver.

Merci encore
windmastr26 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 12h12   #12
Expert Confirmé Sénior
 
Avatar de f-leb
 
Homme Fabien
Enseignant
Inscription : janvier 2009
Messages : 2 410
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 41
Localisation : France, Sarthe (Pays de la Loire)

Informations professionnelles :
Activité : Enseignant

Informations forums :
Inscription : janvier 2009
Messages : 2 410
Points : 4 439
Points : 4 439
je ne sais pas si ça vient de là mais dans ta requête initiale:

Code sql :
...,(SELECT TOP 1 ... ORDER BY DateDocument DESC) AS Delai...

est en contradiction avec:

Citation:
Envoyé par windmastr26
...c'est afficher la liste des articles avec, pour chacun d'eux, le délai de livraison (Delai) correspondant à la commande la plus ancienne (Date).
pour la plus ancienne date, il aurait fallu mettre:
Code sql :
...,(SELECT TOP 1 ... Order by DateDocument asc) as Delai...

d'où peut-être la différence obtenu avec mon:
Code sql :
SELECT codearticle,MIN(datedocument) AS mindedatedocument...

EDIT: même si elle n'est pas encore tout à fait au point, est-ce que la requête est quand même plus rapide ?
f-leb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/05/2011, 17h03   #13
Membre du Club
 
Avatar de windmastr26
 
Homme
Développeur informatique
Inscription : juillet 2009
Messages : 176
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juillet 2009
Messages : 176
Points : 48
Points : 48
Bonjour à tous.

Désolé pour la réponse tardive.

A ce jour, voici la requête qui fonctionne et donne, à mon goût, un temps de réponse très satisfaisant (testé sur une base de 14 000 articles et 33 000 commandes) :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT 
  a.code,
  a.codebarre, 
  a.nom,
  a.emplacement,
  a.qtecdt,
  a.fr, 
  a.prixpiece,
  a.stockmingen,
  a.stockmaxgen,
  a.stockphygen,
  a.reliquatfseur,
  b.DateDocument & ' (' & b.Delai & ')' as delai
FROM Article a
LEFT JOIN (
   SELECT TOP 1 codearticle,codedocument,DateDocument,Delai, lignesoldee
   FROM entetecdefournisseur,lignecdefournisseur
   WHERE lignecdefournisseur.codedocument=entetecdefournisseur.code
   AND quantite<>qtelivree
   ORDER BY codearticle ASC, datedocument DESC
) as b
ON a.code=b.codearticle
Merci encore pour votre aide
windmastr26 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 18h39.


 
 
 
 
Partenaires

Hébergement Web