2009-05-20 6 views
8

J'utilise la déclaration suivanteAccéder à SQL en utilisant TOP 5 en retournant plus de 5 résultats?

SELECT TOP 5 rootcause, COUNT(IIF(accountability="Team 1",1,0)) 
FROM MOAQ 
WHERE CDT=1 
GROUP BY rootcause 

MOAQ est une autre requête qui retourne environ 20 champs de 4 tables, rien de spécial. Cela fonctionne comme prévu et je reçois 5 résultats.

Si j'ajoute une clause ORDER BY sur le champ conditionnel bien que je commence à obtenir 8 résultats. Si je trier par le premier champ, il n'y a pas de problème.

Quelqu'un sait ce qui pourrait se passer?

Modifier pour clarifier - Je ne fais que tester à partir d'Access 2003 à ce stade, déclaration éventuelle sera paramétrée requête via ADO à partir du frontal Excel.

+0

Est-ce que cela provient d'Access ou accédez-vous à Access à partir d'un programme? Si ce dernier, quelle chaîne de connexion utilisez-vous? Aussi, avec quelle version d'Access travaillez-vous? – AnonJr

Répondre

28

Ceci est un effet connu de la directive top dans Access, mais il est pas très bien connu ...

La directive top ne retourne pas les n top articles, comme on est facilement amené à croire. Au lieu de cela, il renvoie au moins n éléments distincts déterminés par l'ordre du résultat.

Dans la plupart des cas, c'est la même chose, mais dans votre exemple où les 5e à 8e articles ont la même valeur de commande, ils sont tous inclus. Il renvoie les cinq premiers éléments, mais également tous les éléments qui ont la même valeur de commande que le cinquième élément.

Si vous n'appliquez aucune commande à la table, tous les champs sont pris en compte. Par conséquent, si vous avez un champ unique dans le résultat, la requête renvoie toujours cinq éléments. La même chose bien sûr si le champ unique est inclus dans la commande.

D'autres dialectes de SQL peuvent se comporter différemment. La directive top seule dans T-SQL (SQL Server) par exemple ne renvoie jamais plus de n éléments. Cependant, en spécifiant les clauses with ties et order by avec top, on peut observer le même comportement que dans Access.

+2

+1 Intéressant! Les effets connus qui ne sont pas connus – Andomar

+0

Très intéressant, merci – Lunatik

1

Accédez à la page des noms d'aide Access 2003 About ANSI SQL query mode (MDB), puis développez la rubrique "Pourquoi utiliser ANSI-92 SQL?" sujet et vous verrez ceci:

« Utilisation de la LIMITE A nn RANGS clause visant à limiter le nombre de lignes renvoyées par une requête »

Il suffit donc de mettre l'interface d'accès en ANSI-92 Mode de recherche ou utiliser OLE DB (par exemple ADO) dans le code et ajouter la clause

LIMIT TO 5 ROWS 

à votre requête.

...

Je plaisante! Ceci est simplement un autre exemple de la piètre documentation du moteur de base de données Access. Je pense que quelqu'un dans l'équipe de documentation Access a fait l'hypothèse pas trop déraisonnable que le mode de requête ANSI-92 du moteur de base de données Access serait conforme à la norme ISO/ANSI SQL-92. Ce n'est pas. Le moteur de base de données Access a sa propre syntaxe propriétaire (c'est-à-dire non-SQL-92 Standard) TOP n (à ne pas confondre avec la propre syntaxe TOP n propriétaire de SQL Servers qui est sémantiquement différente). En un mot, cela ne résout pas les doublons.Si les critères satisfont toutes les lignes de la table, vous obtiendrez toutes les lignes de la table dans le jeu de résultats.

La solution de contournement consiste à utiliser un curseur pour lire uniquement les n premières lignes du jeu de résultats. Étant donné que la base de données SQL Access ne prend pas en charge le code de procédure ou les curseurs explicites, vous devez le faire du côté "client", par exemple. Ouvrez un objet Recordset et lisez les n premiers enregistrements dans un jeu d'enregistrements ADO fabriqué.

+1

L'autre solution, comme implicite dans l'autre réponse ci-dessus, est de choisir un champ «tie-breaker», tel qu'un champ de clé primaire, et de l'ajouter à 'ORDER BY 'clause. –

Questions connexes