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 01/04/2011, 14h37   #1
Nouveau Membre du Club
 
Avatar de popoliline
 
Inscription : juillet 2006
Messages : 86
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : juillet 2006
Messages : 86
Points : 30
Points : 30
Par défaut RechDom() mauvaise Syntaxe

Bonjour,

Je bloque sur la syntaxe d'une requête pour laquelle je voudrais utiliser la fonction RechDom().
J'ai regardé le tuto sur les fonctions de domaines qui m'a bien aidé pour la fonction SomDom(), un peu partout sur le net, mais là je sèche un peu

Mon contexte:
Je recherche l'occupation majoritaire d'une parcelle qui est divisée en "SUF" (1 parcelle = 1 à n SUF)
Donc pour simplifier j'ai une table SUF composée de :
- ID_SUF (Texte) clé primaire
- ID_PARC (Texte)
- Surface (Surface de la SUF) (Numérique)
- TYPE (occupation de la SUF Près, vignes ...) (Numérique)

un exemple :
Citation:
ID_PARC |ID_SUF |Surface |TYPE
1 | 1 |1000 | 1
1 | 2 |300 | 13
1 | 3 |700 | 2
1 | 4| 1500 | 13
2 | 5| 500 | 2
2 | 6| 200 | 5
3 | 7| 1700 | 13
Je cherche à obtenir pour chaque parcelle :
La surface totale, OK
La surface majoritaire, OK
Code :
SURF_MAJO: RechDom("Max([SUF].[Surface])";"[SUF]";"[ID_PARC]='" & [ID_PARC] & " '")
La surface bâtie, OK (fonction somdom() avec un critère sur le TYPE=13)
Code :
SURF_BATIE: CDbl(nz(SomDom("[Surface]";"[SUF]";"[ID_PARC] ='" & [ID_PARC] & "' AND [TYPE]=13");0))
Mais pour obtenir le type majoritaire, la je bloque

Donc je suis finalement partie sur 2 requêtes :
- Une première pour calculer la surface majoritaire pour chaque parcelle
- une seconde qui utilise la première pour rechercher le type d'occupation en fonction de la surface majoritaire précédemment calculé mais il me revoit l'erreur "l'expression entrée comme paramètre de requête est à l'origine de l'erreur suivante : impossible pour MS Access de trouver le nom SUF_MAJO entré dans l'expression"
Pour une premier test j'ai utilisé une valeur fixe
Code :
TYPE_MAJO: RechDom("[SUF].[TYPE]";"[SUF]";"[SURF_MAJO]=1500")
Résultat, le TYPE_MAJO est vide, j'aurais souhaité obtenir 13 pour la parcelle 1
Citation:
ID_PARC |SURF_TOTALE| SURF_MAJO | SURF_BATIE| TYPE_MAJO
1 | 3500 | 1500 | 1800 |
2 | 700 | 500 | 0 |
3 | 1700 | 1700 | 1700 |
Donc je n'arrive pas trop à voir le pb, si vous aviez une petite piste
Peut-on le faire en une seule requête sachant que pour obtenir le type majoritaire il faut utiliser un champ calculé sur la surface majoritaire ?
popoliline est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/04/2011, 17h32   #2
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 256
Points : 5 256
Bonjour,

Le langage SQL a ses propres fonctions que l'on peut utiliser sur des regroupements :

Code sql :
1
2
3
SELECT [ID_PARC], Max(Surface) AS MS
FROM SUF
GROUP BY [ID_PARC]

A+
__________________
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 01/04/2011, 18h39   #3
Nouveau Membre du Club
 
Avatar de popoliline
 
Inscription : juillet 2006
Messages : 86
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : juillet 2006
Messages : 86
Points : 30
Points : 30
Bonsoir,
Merci User pour cette réponse. effectivement ca peut me simplifier une partie de la requête

Par contre je bloque toujours pour récupérer le TYPE_MAJO pour une parcelle donnée et la je ne peux pas utiliser de fonction type Max() ou autre vu qu'il faut récupérer le Type de sol associé à la SURF_MAJO
En fait je le vois comme l'équivalent de la fonction RechercheV sur excel, sauf que là ca ne passe pas ... je n'arrive pas à l'appliquer

Juste pour simplifier, par exemple si pour une parcelle 1 j'ai la table SUF :
Citation:
SUF | Surface | Type
1 | 200 | 5
2 | 500 | 2
3 | 800 | 4
je fais une Requête1 avec pour résultat
Citation:
PARC | SURF_MAJO
1 | 800
Ensuite en Requête2, j'utilise ma table SUF et la Requête1 pour essayer de récupérer le Type_Majo
Citation:
PARCELLE | SURF_MAJO | TYPE_MAJO
1 | 800 | 4
J'ai tenté ceci mais j'obtiens tjs la même erreur citée :
Code :
TYPE_MAJO: RechDom("[SUF].[TYPE]";"[SUF]";"[SURF_MAJO]=" & [SURF_MAJO])
Je suis peut être sur la mauvaise piste et je me complique trop la vie.
Si quelqu'un voit une autre solution, merci
popoliline est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/04/2011, 19h30   #4
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 256
Points : 5 256
Salut,

Essaie ceci:

Code :
1
2
3
4
SELECT SUF.ID_PARC, SUF.SURFACE AS MS, SUF.TYPE AS TYPE_MAJO
FROM SUF
WHERE ((SUF.SURFACE In (select Max(SURFACE) as MS From SUF S Where S.ID_PARC=SUF.ID_PARC)))
ORDER BY SUF.ID_PARC;
A+
__________________
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 10
Vieux 01/04/2011, 19h46   #5
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Bonsoir,

Si j'ai bien compris tu pars d'une requête qui sélectionne des parcelles.
Code :
1
2
SELECT DISTINCT SUF.ID_PARC
FROM SUF;
Ensuite tu ajoutes des champs calculés (colonnes).

Champ calculé SURF_MAJO pour la surface la plus grande de la parcelle :
Code :
SURF_MAJO: MaxDom("Surface"; "SUF"; "[ID_PARC]=" & [ID_PARC])
Champ calculé SURF_BATIE pour la surface bâtie :
Code :
SURF_BATIE: CDbl(Nz(SomDom("Surface"; "SUF"; "[ID_PARC] =" & [ID_PARC] & " AND [TYPE]=13"); 0))
Enfin, un champ calculé TYPE_MAJO pour le type de la surface la plus grande :
Code :
TYPE_MAJO: RechDom("[TYPE]"; "SUF"; "[Surface]=" & [SURF_MAJO])
Tu notera que dans le troisième argument le critère est le champ Surface de la table SUF.
Tu ne peux pas mettre un critère sur [SURF_MAJO] car ce n'est pas un champ de la table SUF.

A+
LedZeppII est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 04/04/2011, 10h27   #6
Nouveau Membre du Club
 
Avatar de popoliline
 
Inscription : juillet 2006
Messages : 86
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : juillet 2006
Messages : 86
Points : 30
Points : 30
Bonjour,
Merci beaucoup à vous deux de vous être penchés sur mon pb

User, ta solution fonctionne en partie car j'obtiens le TYPE_MAJO mais par contre pour une seule et unique parcelle, celle qui a la SUF la plus grande parmi toutes les SUF de toutes les parcelles. Donc j'ai essayé de comprendre ce que tu me proposais mais je n'ai pas réussi à le modifier pour l'obtenir pour chaque parcelle

Par contre LedZeppII ta solution fonctionne très bien.
Je n'étais finalement pas très loin du vrai
J'ai juste fait une modification pour le champs calculé SURF_MAJO (bcp plus simple que mon calcul) afin d'obtenir un champs numérique avec la fonction CDbl() et j'ai rajouté quelques ' et " car mon ID_PARC est en alphanumérique :
Code :
SURF_MAJO: CDbl(MaxDom("Surface";"SUF";"[ID_PARC]='" & [ID_PARC] & " '"))
Par contre si j'ajoute le champs calculé TYPE_MAJO dans la même requête, je doit rentrer un paramètre pour SURF_MAJO
Si je rentre une valeur bidon, la requête se lance et donne le bon résultat
Par contre, si je valide sans rentrer de valeur j'ai le message d'erreur suivant
Citation:
erreur de syntaxe (opérateur absent) dans l'expression "[Surface]="
J'ai essayé de trouver une solution mais j'ai finalement contourné le pb en passant par une deuxième requête.

Mais en fait je suis confrontée à un nouveau problème au niveau du temps de traitement
J'avais fait une base test de quelques enregistrements pour faciliter la création des requêtes
Maintenant en voulant les utilisant sur ma base de travail, je ne pensais pas que cela ferait planter Access car j'ai plus de 70 000 lignes à traiter
J'ai également réduit le nombre de lignes en ne travaillant que sur 1 commune (certaines ont 7 500 lignes d'autres 35 000 lignes) car j'en ai 8 au total mais même là Access ne répond plus je suis carrément obligée d'arrêter le processus ...

Y aurait-il une solution pour faire / accélérer le traitement ? passer carrément par un module ?

Encore merci pour votre aide
popoliline est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2011, 15h09   #7
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 256
Points : 5 256
Citation:
User, ta solution fonctionne en partie car j'obtiens le TYPE_MAJO mais par contre pour une seule et unique parcelle, celle qui a la SUF la plus grande parmi toutes les SUF de toutes les parcelles. Donc j'ai essayé de comprendre ce que tu me proposais mais je n'ai pas réussi à le modifier pour l'obtenir pour chaque parcelle
J'ai pourtant testé ma requête et elle fonctionne très bien

Pourrais tu la recopier et la tester une nouvelle fois

parce que avec le :
Code :
Where S.ID_PARC=SUF.ID_PARC
Tu ne devrais pas avoir le problème que tu mentionnes...

A+
__________________
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 04/04/2011, 15h29   #8
Nouveau Membre du Club
 
Avatar de popoliline
 
Inscription : juillet 2006
Messages : 86
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : juillet 2006
Messages : 86
Points : 30
Points : 30
Bonjour User,
Effectivement, gros mea culpa, j'ai retesté et je retrouve bien la surface majoritaire par parcelle .. pourtant il me semblait bien avoir fait un copier/coller de ce que tu me proposait vendredi. C'est même pour cela que j'ai fait quelques recherches ce weekend avant de répondre car je ne comprenais pas pourquoi je n'obtenais qu'une parcelle au final.
L'essentiel c'est que cela fonctionne, merci.

Mais en même temps, j'ai toujours autant de mal à traiter mes données niveau rapidité de traitement. Rien que l'affichage du résultat met au moins 15s, autant de temps dès que je veux vérifier quelques enregistrements. Donc j'avais pensé créer une requête création de table mais je n'arrive pas à savoir si la requête est en cours ou si c'est un plantage, donc je termine le processus
J'ai même testé l'export en .dbf et j'ai à peine sorti 3500 lignes en 15min ... j'ai tenté le copier/coller directement mais pareil, l'ordi rame ...
je suis pas rendu pour les 37000 lignes que j'ai à traiter après regroupement.
Je crois que je commence à voir les limites d'Access ...

Quelqu'un aurait-il une piste à étudier ?
Sachant que je dois prioritairement utiliser Access, mais si une autre solution est à envisager je peux aussi m'y pencher.
Merci
popoliline est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2011, 21h59   #9
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Par défaut à tester

Bonsoir,

C'est normal que ce genre de requête soit peu performante.
Chaque fonction de regroupement domaine (MaxDom, SomDom, RechDom) est une sous-requête.
Essaie de voir le temps qu'il faut pour 3 x 32700 requêtes.

Ceci dit, passer par une table intermédiaire (voir même plusieurs) peut améliorer les performances.

Première requête pour créer une table SUF_TMP :
Code :
1
2
3
4
5
6
7
8
SELECT DISTINCT SUF.ID_PARC, 
    CLng(0) AS ID_SUF, 
    Max(SUF.Surface) AS SURF_MAJO, 
    (SELECT CLng(Nz(Sum(SUF2.Surface), 0)) FROM SUF As SUF2 WHERE SUF2.ID_PARC = SUF.ID_PARC And SUF2.[Type]=13) AS SURF_BATIE,
    CLng(0) AS TYPE_MAJO
INTO SUF_TMP
FROM SUF
GROUP BY SUF.ID_PARC;
A l'issue de cette requête on a la plus grande surface et la surface bâtie.

Deuxième requête pour le type de la surface majoritaire, et son id :
Code :
1
2
3
UPDATE SUF_TMP INNER JOIN SUF ON (SUF_TMP.ID_PARC = SUF.ID_PARC) AND (SUF_TMP.SURF_MAJO = SUF.Surface) 
SET SUF_TMP.ID_SUF = [SUF].[ID_SUF], 
    SUF_TMP.TYPE_MAJO = [SUF].[TYPE];
A+
LedZeppII est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/04/2011, 14h34   #10
Nouveau Membre du Club
 
Avatar de popoliline
 
Inscription : juillet 2006
Messages : 86
Détails du profil
Informations personnelles :
Localisation : France

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : juillet 2006
Messages : 86
Points : 30
Points : 30
Bonjour,
Merci beaucoup pour ce complément.
Effectivement ce n'est pas le plus pratique niveau rapidité.
J'avais déjà lancé un export en txt que j'ai ensuite réimporté dans Access avant ta proposition, c'est de la bidouille mais pas trop le choix.
Ta solution fonctionne bien sur ma base essai mais je n'ai pas pris le temps de la tester sur ma base de travail. Je l'aurais pour le prochain coup et ca m'a aussi permis de découvrir de nouvelle fonction
popoliline 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 04h14.


 
 
 
 
Partenaires

Hébergement Web