FAQ MS-Access
FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
- Quelle est la différence entre DISTINCT et DISTINCTROW ?
- Comment éviter les doublons dans une requête (pour charger une zone de liste par exemple) ?
- Comment fonctionnent les jointures/relations ?
- Requête donnant la liste des enregistrements de la table 1 qui ne sont pas dans la table 2
- Comment, dans une requête, ajouter un champ "ordre" qui s'incrémente pour chaque identifiant ?
- Comment chercher en SQL le premier ou dernier enregistrement d'une table ?
- Comment calculer le nombre d'enregistrements correspondant au critère de la requête ?
- Regroupement (GROUP BY) sur les n premières lettres des enregistrements d'un champ ?
- Comment n'avoir que les x premières réponses d'une requête ? (Comme LIMIT en MySQL)
- Pourquoi ma requête fonctionne-t-elle avec l'opérateur In, mais pas avec l'opérateur Not In ni même Not Exist ?
- Comment faire une requête qui ne retourne que les enregistrements d'un intervalle désiré ? (Limit 50,50 de MySQL) ?
- Comment ne sélectionner que les enregistrements qui diffèrent entre deux champs de deux tables distinctes ?
- Comment retourner toutes les lignes de deux ensembles avec UNION ?
- Comment vider rapidement une table attachée en ODBC ?
- Comment catégoriser des clients (réductions) pour éditer une facture ?
- Comment créer une numérotation dans une requête ?
Il y a une grosse différence entre DISTINCTROW et DISTINCT.
- On utilise DISTINCTROW lorsque l'on choisit de travailler sur des lignes qui à l'origine sont sans doublon.
si ma table contient :
Nom ------- Prénom
Dupont ---- Jean
Dupont ---- Pierre
Dupond --- Jean
Dupont ---- Jean
un
Select
DistinctRow NOM From MATABLE
me renverra :
Dupont Dupont Dupond
Car j'ai 2 Dupont Jean(1), 1 Dupont Pierre(2) et 1 Dupond Jean(3)
- Contrairement au DISTINCTROW, le DISTINCT s'intéresse quant à lui au résultat affiché. Il n'affiche que des lignes sans doublon. Ainsi, avec la même table que précédemment, un petit
Select
Distinct NOM From MATABLE
ne renverra que :
Dupont Dupond
Il suffit d'utiliser "DISTINCT" dans la requête source. Exemple :
Select
distinct NOM From TEMPLOYE;
Vous obtiendrez tous les noms des employés. Si plusieurs employés ont le même nom, il n'apparaîtra qu'une fois.
Maxence HUBICHE vous dévoile tout ce que vous avez besoin de savoir sur les jointures, à quoi elles servent et comment les mettre en place.
Select
LECHAMP From TABLE1 Where LECHAMP Not
In
(
Select
LECHAMP2 From TABLE2);
Imaginons qu'un employé a eu plusieurs promotions au cours de sa carrière.
Chaque promotion est stockée avec sa date d'obtention.
On veut avoir le récapitulatif des promotions de chaque employé. On veut aussi connaître le numéro de la promotion (3 si c'est la troisième promotion de l'employé...).
Select
*
, (
Select
Count
(*
) From LATABLE T2 Where T2.ID
=
T1.ID
And
T2.DATE
<=
T1.DATE
) As
NUMORDRE
From LATABLE T1;
Pour le premier :
Select
First
(
MONCHAMP) From LATABLE;
Pour le dernier :
Select
Last
(
MONCHAMP) From LATABLE;
Il faut utiliser count() sur le(s) champ(s) concerné(s).
Pour en savoir plus --> https://sqlpro.developpez.com/SQL_AZ_2.html#SELECT_stat
Exemple :
Select
count
(
CHAMP1) From LATABLE Where CHAMP2 =
3
And
CHAMP3 LIKE "*blabla*"
Lien : Comment compter le nombre d'enregistrements d'une table ou d'une requête ?
Utile par exemple pour le code postal (français), pour grouper par département :
Select
Distinct Left
(
LECHAMP,2
) As
CODE_POSTAL
From PERSONNE;
Deux solutions :
Select
TOP 5
PERCENT MATABLE.MONCHAMP1
, MATABLE.MONCHAMP2
From MATABLE;
Pour récupérer 5 lignes sur 100 (5 %)
Select
TOP 5
MATABLE.MONCHAMP1
, MATABLE.MONCHAMP2
From MATABLE;
Pour récupérer 5 lignes.
Ceci peut se produire lorsque la sous-requête renvoie des valeurs Nulles.
La solution est donc de filtrer ces valeurs directement dans la sous-requête en spécifiant par exemple une clause Where.
Par exemple :
Select
MATABLE.CHAMP1
From MATABLE Where MATABLE.CHAMP1
Not
In
(
Select
MONCHAMP Where ((
tbl.LaDate
) Is
Not
Null
))
Select
MATABLE.CHAMP1
From MATABLE Where MATABLE.CHAMP1
Not
In
(
Select
MONCHAMP Where Not
IsNull
(
MONCHAMP))
Comment faire pour qu'une requête ne renvoie que les enregistrements 50 à 100 par exemple ?
Ceci est facilement possible sous MySQL en passant par un "LIMIT 50,50", mais n'existe pas encore sous Access.
Il est cependant possible d'arriver à nos fins grâce à diverses astuces :
En créant deux requêtes. Une qui sélectionne les 100 enregistrements, puis une seconde qui ne sélectionne que les 50 derniers enregistrements de la requête précédente. Ainsi nous aurons bien les enregistrements 50 à 100.
Créons donc la première requête que nous nommerons "Req1"
Select
TOP 100
ID, ladate
FROM LaTable
Order By ladate Asc
;
Ensuite, il ne reste qu'à sélectionner les 50 derniers enregistrements de la requête ci-dessus :
Select
TOP 50
ID, ladate
FROM Req1
OrderBy ladate Desc;
En passant par DAO et un tableau. Vous trouverez les détails de cette fonctionnalité DAO dans le tutoriel de Tofalu dont le lien est ci-dessous.
Une fois les données d'un Recordset dans un tableau, vous pouvez atteindre très facilement les enregistrements désirés.
Lien : Définition et manipulation de données avec DAO par Tofalu
Select
*
From Table1 AS
T1
Where Not
Exists (
Select
null
From Table2 AS
T2
Where T1.
[champT1]=
T2.
[champT2])
Cette requête sélectionnera tous les enregistrements de Table1 dont le champ "champT1" possède une valeur ne se trouvant pas dans le champ "champT2" de la seconde table.
Une requête UNION élimine les doublons dans les lignes qu'elle renvoie. Pour forcer la clause UNION à conserver les doublons dans les résultats retournés, utilisez UNION ALL en mode SQL.
SELECT
*
FROM
TABLE1
UNION
ALL
SELECT
*
FROM
TABLE2
La commande SQL TRUNCATE n'est pas reconnue par Access. Il faut donc utiliser une requête SQL Direct pour passer l'ordre SQL directement au moteur de base de données (MySQL) par exemple.
Vous pouvez ainsi exécuter n'importe quelle requête compatible avec le serveur qui était incompatible avec le SQL de Jet.
1. Créez la liaison ODBC avec le gestionnaire de liaisons (Démarrer -> paramètres -> source de données ODBC). Dans cet exemple, la base s'appelle "base_MySQL" sur le serveur "nom_du_serveur".
2. Créez la requête avec Créer une requête en mode création. Fermez la liste des tables et requêtes. Clic droit sur la table -> Spécifique SQL -> SQL Direct.
3. Écrivez la requête
TRUNCATE
Matable;
4. Dans la barre de titre de la requête, clic droit -> propriétés ->Chaîne connexion ODBC : Indiquez le chemin de connexion sous la forme
ODBC;DATABASE
=
base_MySQL;DSN=
base_MySQL;OPTION
=
0
;PORT
=
0
;SERVER
=
nom_du_serveur;
5. Exécutez la requête. Un message d'avertissement apparaît car la requête ne renvoie rien (forcément, c'est une requête de destruction de données !).
Pour éviter ce message, vous pouvez modifier la propriété Renvoie enr. de la requête SQL Direct à Non.
Nous allons dans cette Q/R expliquer comment catégoriser des clients pour leur attribuer une réduction qui sera déduite sur la facture.
Pour cela nous allons développer trois méthodes :
Méthode statique
Les taux de remises sont écrits directement dans le code.
=
montant -
(
montant *
iif
(
categorie like "A"
;0
.1
;iif
(
categorie like "B"
;0
.2
;0
.3
)))
montant est le champ contenant la somme.
catégorie est le champ contenant la catégorie client.
Deux inconvénients :
- l'imbrication des iif qui peut prendre des proportions avec la quantité de catégories ;
- l'obligation d'éditer le code lorsque l'on ajoute ou change une catégorie.
Notez qu'avec une catégorie numérique 1 au lieu de A, 2 au lieu de B... on peut utiliser Choose() qui se réduit à une fonction au lieu d'une par catégorie.
Méthode paramétrée
Cette méthode a deux avantages :
- l'ajout, la modification, la suppression de catégorie peuvent se faire par l'utilisateur, pas de code à modifier ;
- pas d'imbrication de iif().
Inconvénient :
on doit créer une table supplémentaire pour gérer les remises.
Table : tbl_param
Champ 1 : param (texte 1) contient A, B, C
Champ 2 : valeur (double) contient la remise sous forme 0.1, 0.2...
=
Montant -
(
Montant *
dlookup
(
"Valeur"
;"tbl_param"
;"Param like "
&
Categorie))
3e méthode
De loin la plus simple.
Catégorie ne contient pas A B ou C mais directement 1, 2, 3 (la valeur de la remise * par 10)
=
Montant -
(
Montant *
Categorie/
10
)
Voici un exemple en utilisant la fonction de Domaine DCount
Soit une table (tbl_DetailFacture) avec trois champs
- strArticle
- lngQte
- curPrixUnit
Le code classe par ordre croissant les prix unitaires
SELECT
strArticle,lngQte,curPrixUnit, DCount(
"[strArticle]"
,"[tbl_DetailFacture]"
,"[CurPrixUnit]<="
&
[CurPrixUnit]
)
AS
Cumul
FROM
tbl_DetailFacture
ORDER
BY
curPrixUnit;
Ceci donne dans le champ cumul une numérotation des enregistrements.
Pour que cela fonctionne correctement, il faut que la clause de la fonction de Domaine DCount soit sur le champ que l'on veut trier.
Lien : Classer les résultats d'une requête
Lien : Classer des données par plage