Page 1 sur 3

Pb Requete SQL !!!!

Posté : 13 mars 2006, 19:07
par TOMITOMAS
Bonjour,

j'ai un petit probleme sur une requete SQL !!! (fais sous Access)

la BD me permet de gérer des dossiers, pour faire simple, je ne vais énoncer que les champs dont j'aurai besoin.

Pour commencer, j'ai une table principale "FINANCE" ou apparait les éléments suivants :
  • le nom d'un vendeur
  • une zone
  • un numéro de carte
  • un numéro d'autorisation
le numéro de carte peut etre :
  • soit un numéro
  • soit un attribut de la table "ACTIVITE"
le numéro d'autorisation peut etre :
  • soit un numéro
  • soit un attribut de la table "AUTO"
les tables "ACTIVITE" et "AUTO" ont des attributs de type chaine de caractères, et n'ont une seule colonne.
Une vendeur dépend d'une zone.

un dossier est accepté si le numéro de la carte ET le numéro d'autorisation sont des numéros ( donc si aucun des deux n'apparaissent dans les table "ACTIVITE" et "AUTO")
un dossier est refusé si le champs 'numéro d'autorisation' vient de la table "AUTO"


la requete que je souhaite réaliser est la suivante :
compter le nombre de dossiers acceptés ET refusés pour chaque vendeur de chaque zone

ma requete qui ne fonctionne pas (!!!) : 'erreur synthaxe dans l'instruction JOIN'

Code : Tout sélectionner

SELECT finance.zone, finance.vendeur, nombre1, nombre2 FROM (SELECT A.zone, A.vendeur, count(A.zone) as nombre1 FROM finance AS A WHERE A.NumCarte NOT IN (SELECT * FROM ACTIVITE) AND A.NumAuto NOT IN (SELECT * FROM AUTO) Group By A.zone, A.vendeur) LEFT JOIN ((SELECT R.zone, R.vendeur, count(R.zone) as nombre2 from finance AS R WHERE R.NumAuto In (SELECT * FROM AUTO) Group By R.zone, R.vendeur) LEFT JOIN finance ON (R.vendeur = finance.vendeur) AND (R.zone = finance.zone)) ON (A.vendeur = finance.vendeur) AND (A.zone = finance.zone) GROUP BY finance.zone, finance.vendeur ;

Quelqu'un aurait il une petite idée, ou un petit coup de pouce a me donner ???
D'avance merci beaucoup !!

Posté : 13 mars 2006, 19:19
par Cyrano
C'est un ppeu fouillis, faudrait analyser en profondeur pour reconstituer la structure: tu aurais pas un schéma des tables avec les colonnes et les clés ?

Edit : en regardant la requête de plus près, je note quand même des erreurs et des inversions de positions. Proposition sans aucune forme de garantie de résultat:

Code : Tout sélectionner

SELECT finance.zone, finance.vendeur, nombre1, nombre2 FROM (SELECT A.zone, A.vendeur, count(A.zone) as nombre1 FROM finance AS A WHERE A.NumCarte NOT IN (SELECT * FROM ACTIVITE) AND A.NumAuto NOT IN (SELECT * FROM AUTO) Group By A.zone, A.vendeur) LEFT JOIN ((SELECT R.zone, R.vendeur, count(R.zone) as nombre2 from finance AS R LEFT JOIN finance ON (R.vendeur = finance.vendeur) WHERE R.NumAuto In (SELECT * FROM AUTO) AND (R.zone = finance.zone) Group By R.zone, R.vendeur) ) ON (A.vendeur = finance.vendeur) WHERE (A.zone = finance.zone) GROUP BY finance.zone, finance.vendeur ;
Mais j'ai un gros doute. Je suis sûr qu'on peut largement simplifier ça, il faudrait voir la structure de tes tables et les liens PK/FK.

Posté : 13 mars 2006, 20:35
par TOMITOMAS
Tout d'abord, merci pour ta réponse !!

voici les relations qu'il y a entre les tables :
[schéma !]
est ce que c'est ce que tu veux ??
désole je ne suis pas encore un adepte des forum, je découvre ...

Posté : 13 mars 2006, 20:37
par Cyrano
C'est parfait pour le schéma : en revanche, ce qu'il m'indique est plus ennuyeux: je ne vois pas tes clés primaires/clés étrangères : comment veux-tu faire des jointures ? :-k

Posté : 13 mars 2006, 20:43
par Invité
les clés sont en gras !!
finance : Num (un numéro incrémenté tout le temps)
AUTO : rens
ACTIVITE : activite

mais les jointures se font sur la meme table (finance) ???

les deux autres tables permettent juste d'avoir un choix possible pour remplir les 2 attributs 'NumCarte' et 'NumAuto' de la table finance si on en a besoin.

(je ne passe pas par un code de malade pour remplir mes tables !! c'est fait sous access pour le moment ! en ouvrant tout simplement le fichier !!! )

Posté : 13 mars 2006, 20:55
par Cyrano
Bon, ok, ça évolue un peu, j'essaye de comprendre ce qui correspond à quoi : quelle colonne indique refusé/accepté ?

Posté : 13 mars 2006, 21:05
par TOMITOMAS
il n'y en a pas justement !!!
c'est justement là ou ca devient "difficile" de gérer tout ca ....

pour résumer :
dans la table 'activite' tu peux trouver par exemple : '10x', '3x', 'credit', ...
dans la table 'auto' tu peux trouver par exemple : 'etude', 'annulé', 'renseigné', ...

soit les champs 'NumCarte' et 'NumAuto' contiennent des numéro (donc pas d'attributs d'une des tables 'auto' et 'activite') => le dossier est accepté
soit le champ 'NumAuto' est complété grace aux attributs de la table 'auto' => le dossier est refusé

peut etre que les code t'aideront a mieux comprendre :

dossier accepté :

Code : Tout sélectionner

SELECT finance.BA, finance.vendeur, Count(finance.BA) AS ACCEPTES FROM finance WHERE finance.date=Date() AND finance.NumCarte Not IN (SELECT * FROM ACTIVITE) AND finance.NumAuto Not IN (SELECT * FROM AUTO) GROUP BY finance.BA, finance.vendeur, finance.date;
dossier refusé :

Code : Tout sélectionner

SELECT finance.BA, finance.vendeur, Count(finance.BA) AS REFUSES FROM finance WHERE finance.date=Date() AND finance.NumAuto IN (SELECT * FROM AUTO) GROUP BY finance.BA, finance.vendeur, finance.date;

Posté : 13 mars 2006, 21:10
par Cyrano
Ce que je ne comprends pas, ce sont tes deux tables satellites: telles que présentées, elles ne servent strictement à rien. Si tu n'a dans chacune de ces deux tables qu'une seule et unique colonne qu'on retrouve ou non dans la table finance, ça ne fait qu'un doublon: tu pourrais donc aussi bien les supprimer purement et simplement.

Pour ce qui est de définir un dossier accepté ou refusé, je trouve la technique terriblement complexe: pourquoi ne pas voir simplement un champ avec un type Booléen avec 0 pour "refusé", 1 pour "accepté" voire éventuellement 2 pour "non traité" :-k

À partir de là, ce serait largement plus simple que des jointures gauches à n'en plus finir...

Posté : 13 mars 2006, 21:17
par TOMITOMAS
* pour ta 1ere remarque :
j'ai besoin de ces 2 tables annexes !! ca va devenir compliquer de tout expliquer :) pk ??? parce que tout simplement il peut y avoir de nouvelle 'activite' il faut donc que je puisse les rajouter, sans avoir a modifier toutes mes autres requetes (qui se servent justement de ces tables !)
ca ne me fait pas de doublons, ca me sert juste a dire quels seuls choix ont peu avoir (en plus d'un numéro classique)
de meme pour les autorisations ...

* pour la 2e :
le booléan serait tellement simple que ca ne serait pas drole ....
mes collegues bossaient sur un fichier excel plus ou moins similaire depuis de nombreuses années .... (mais toutes les stats étaient à faire a a main, d'ou mon intéret pour un base access) alors va leurs demander de rajouter une colonne et qu'il réfléchisse à ce qu'ils doivent mettre à chaque fois .... :?
pas top !!! deja que j'arrive et que je mets un peu le bordel dans leur organisation....

ceci dit la solution serait top et vraiment facil à gérer !!!
(mais quand c'est trop facil ce n'est pas drole... :) )

Posté : 13 mars 2006, 21:35
par Cyrano
Revenons à tes deux requêtes : tu m'indiques la seconde pour les dossiers refusés, mais le dernier champ est aliasé AS ACCEPTES : c'est normal :?:

Posté : 13 mars 2006, 21:40
par TOMITOMAS
autant pour moi, c'est une erreur de frappe !!! :roll:
le cc/cv ne corrige pas tout tout seul :) je n'y ai pas fait attention !
la 2e requete donne bien les dossiers refusés !
(désolé !!)

Posté : 13 mars 2006, 21:55
par Cyrano
Bon alors sous toutes réserves et sans garanties et en me basan t sur tes deux dernières requêtes, j'essayerais un truc dans ce genre :

Code : Tout sélectionner

SELECT f1.BA, f1.vendeur, Count(f2.BA) AS ACCEPTES, Count(f3.BA) AS REFUSES FROM finance AS f1 LEFT JOIN finance AS f2 ON f1.vendeur = f2.vendeur, LEFT JOIN finance AS f3 ON f1.vendeur = f3.vendeur, WHERE f2.date = Date() AND f3.date = Date() AND f2.NumCarte Not IN (SELECT * FROM ACTIVITE) AND f2.NumAuto Not IN (SELECT * FROM AUTO) AND f3.NumAuto IN (SELECT * FROM AUTO) GROUP BY f1.BA, f1.vendeur, f2.date, f3.date;
Mais j'insiste, sans garantie, faudrait tester et je n'ai pas la base ni de jeu d'essai pour le faire en local.

Posté : 13 mars 2006, 22:17
par TOMITOMAS
deja fait !!! :)
mais ca ne me retourne pas le bon résultat :
je n'ai que les vendeurs ayant des dossiers accpetés ET refusés, si un vendeur a seulement eu un dossier accepté il n'apparait pas.
et j'ai les meme résultats dans les colonnes acceptés et refusés...
:s
c'est vraiment galere !!!!!

Posté : 13 mars 2006, 22:21
par Cyrano
Petite modification alors :

Code : Tout sélectionner

SELECT f1.BA, f1.vendeur, Count(f2.BA) AS ACCEPTES, Count(f3.BA) AS REFUSES FROM finance AS f1 LEFT JOIN finance AS f2 ON f1.vendeur = f2.vendeur, LEFT JOIN finance AS f3 ON f1.vendeur = f3.vendeur, WHERE f2.date = Date() AND f3.date = Date() AND ((f2.NumCarte Not IN (SELECT * FROM ACTIVITE) AND f2.NumAuto Not IN (SELECT * FROM AUTO)) OR f3.NumAuto IN (SELECT * FROM AUTO)) GROUP BY f1.BA, f1.vendeur, f2.date, f3.date;

Posté : 13 mars 2006, 22:22
par TOMITOMAS
si on ne sait pas trouver de réponses, ne pourrait on pas faire la chose suivante :

a partir des 2requetes que j'ai mis plus haut (dossiers acceptés et dossiers refusés), est ce qu'on ne pourrait pas créer une 3e requete qui regrouperait les infos que je désire ??? :roll:
et qui retournerait un tableau avec le BA, le vendeur, le nb de dossiers accpetés et refusés pr celui ci
???