Accéder au contenu principal

Simuler un COUNT DISTINCT avec Access

Le SQL disponible dans les requêtes Access ne dispose pas de l'instruction COUNT DISTINCT, qui permettrait par exemple, de compte combien de clients différents ont commandé, année par année.
Ce prédicat, qui est présent dans SQL Server, peut être simulé de diverses manières, plus ou moins lourdes et plus ou moins efficaces.
Mais la méthode probablement la plus performante est d'utiliser une requête CROSSTAB un peu particulière.

Voici  un exemple sur la base Northwind (ou Comptoirs avec les versions françaises d'Access), dans lequel on va décompter le nombre de clients différents par année, ainsi que le nombre total de commandes:

TRANSFORM Count(*) AS Dist
SELECT Year([OrderDate]) AS Yr, Count(([Dist])) AS DistCustomers, Count(OrderId) AS NumOrders
FROM Orders AS o
GROUP BY Year([OrderDate])
PIVOT CustId In (null);

Pour la voir en action, vous pouvez créer une nouvelle requête dans Northwind, l'afficher en mode SQL, et y coller le code ci-dessus.
Ce type de requête est extrêmement performant: je l'ai utilisé sur des tables de plus de 500.000 records, avec un résultat en quelques secondes.
Sa conception et son adaptation ne sont cependant pas évidents.
L'idée est de créer un entête de colonne (Column Heading) bidon, qui n'apparaîtra pas dans le résultat final, mais qui servira dans l'exemple à obtenir UNE colonne par client (la valeur que l'on veut en DISTINCT). On pourra ensuite calculer combien de colonnes non vides pour chaque ligne, et le tour est joué.

Commentaires

Posts les plus consultés de ce blog

Champs obligatoires dans un formulaire Access

Comment rendre des champs obligatoires dans un formulaire Access ? La réponse la plus évidente est de modifier le design de la table et d'assigner au paramètre Required la valeur True. L'ennui de cette méthode est que le message d'erreur d'Access n'est pas très convivial et ne spécifie pas quel champ a déclenché l'erreur. Plutôt que d'écrire une routine de gestion d'erreur complexe, il y a une solution toute simple: affecter la valeur Faux à la propriété  Required du champ, Validation Rule: Is Not Null Validation Text: le texte à afficher, ex: "Code Postal obligatoire" ..et le tour est joué. Cette astuce vient de l'excellent Allen Browne, dont le site (en anglais) regorge d'informations utiles sur Access. ps: je n'ai pas sous la main de version française d'Access pour la traduction des propriétés, désolé...

ROW_NUMBER OVER PARTITION en Access

Ceux qui ont l'habitude de travailler avec une "grosse" base données comme SQL Server / Oracle / PostGreSQL, sont parfois frustrés face à certaines lacunes du SQL d'Access.   Prenons par exemple: ROW_NUMBER() OVER PARTITION, dont l'absence rend certaines requêtes très compliquées.   J'ai donc écrit une petite fonction VBA qui peut être appelée depuis un query Access et qui simulera assez bien ce ROW_NUMBER() OVER PARTITION.   Notez que ceci ne fonctionnera pas correctement dans une vue ou un formulaire interactif. Par contre comme source d'un rapport ou d'un export Excel, c'est impeccable.   En pratique il est préférable d'initialiser la fonction avec une chaîne de caractères "improbable" avant de lancer le rapport, comme indiqué dans le code.