2009-04-23 10 views
2

dans Access DB ... Je dois extraire la combinaison itemcode/desc pour chaque itemcode dans le tableau suivant où la desc a été utilisée le plus fréquemment.Accéder à la base de données, sélectionner le groupe en ayant le problème max

le plus souvent pourrait vouloir dire qu'il n'y avait qu'une seule version (voir ajoutée record pour la poire)

dans le cas de 777 ItemCode, je vais devoir décider plus tard quelle version la description à utiliser. S'il y a plusieurs enregistrements, chacun contenant une seule version d'une description, cela créera certainement un problème supplémentaire.

la question initiale devrait probablement également inclure le renvoi de la première ligne pour les itemscodes comme 777 où tous les enregistrements existants pour un itemcode contiennent une seule description unique (de sorte que le nombre serait toujours 1). la première rangée n'est pas toujours la bonne version - mais je ne pourrai pas automatiser cette phase de toute façon.

--------------------- 
itemcode | desc 
--------------------- 
123  | apple 
123  | apple 
123  | apple 
123  | apple 2 
123  | apple-2 
001  | orange 
001  | orange 
001  | ORANGE 1 
001  | orange-1 
666  | pear 
777  | bananananana 
777  | banana 

alors - je suis à la recherche de se retrouver avec les éléments suivants:

--------------------- 
itemcode | desc 
--------------------- 
123  | apple 
001  | orange 
666  | pear 
777  | bananananana 

Je pense que je suis proche, mais ce qui suit obtient seulement la description dans la base de données qui apparaît le plus fréquemment et seulement renvoie une ligne.

SELECT itemcode, desc, count(desc) 
from table 
group by itemcode, desc 
having count(desc) = 
(
select max(ct) from 
(
    select itemcode, desc, count(desc) as ct 
    from table 
    group by itemcode, desc 
) 
); 

retours:

--------------------- 
itemcode | desc 
--------------------- 
123  | apple 
+0

J'ai corrigé (et j'ai corrigé les bogues) ma réponse à la question modifiée. – Tomalak

Répondre

3

Cela fonctionnerait par une sous-requête corrélative:

SELECT 
    t.itemcode, t.desc, Count(t.desc) AS CountOfdesc 
FROM 
    [table] AS t 
GROUP BY 
    t.itemcode, t.desc 
HAVING 
    Count(t.desc) IN (
    SELECT TOP 1 
     Count(i.desc) 
    FROM 
     [table] AS i 
    WHERE 
     i.itemcode = t.itemcode 
    GROUP BY 
     i.itemcode, i.desc 
    ORDER BY 
     Count(i.desc) DESC 
) 
    AND t.desc = (
    SELECT TOP 1 
     i.desc 
    FROM 
     [table] AS i 
    WHERE 
     i.itemcode = t.itemcode 
    GROUP BY 
     i.itemcode, i.desc 
    ORDER BY 
     i.desc 
) 
; 

retours (testé avec Access 2003):

 
itemcode desc   CountOfdesc 
001  orange  2 
123  apple   3 
666  pear   1 
777  banana  1 

BTW vous devriez vraiment pas appellerez une table "table" et colonne "desc". Ce sont des mots-clés SQL réservés, il suffit de les éviter pour vous faciliter la vie.

+0

"table" et "desc" étaient juste des doublures, pas les vrais noms. – m42

+0

@ 42: Bon. :) – Tomalak

+1

Oui, confirmé travailler dans Access 2003. Quelle version utilisez-vous? – Tomalak

0

Votre requête renvoie le MAX. Trouvez un moyen de créer une règle qui satisferait vos besoins.

Ce "qui apparaît le plus fréquemment" signifie quoi? apparaît> 2? apparaît> 3? apparaît> 4? ...

+0

Il ne pouvait apparaître qu'une seule fois. Je voudrais aussi cela. – m42

+0

Regardez la réponse de JP. Peut-être que ce sera suffisant pour ce que vous cherchez. :-) – MarlonRibunal

-1

Attendez, pourquoi ne pouvez-vous pas simplement commander par le nombre et prendre le dessus cependant beaucoup que vous voulez? Ai-je mal compris votre question? Par exemple ...

SELECT TOP N itemcode, desc, count(desc) AS [Count] FROM table 
GROUP BY itemcode, desc 
ORDER BY [Count] 

D'accord, que diriez-vous ...

;WITH dt AS 
(
    SELECT 
    ROW_NUMBER() OVER 
    (PARTITION BY itemcode ORDER BY COUNT([desc])DESC) AS 'RowNumber', 
    COUNT([desc]) AS [Count], 
    itemcode, 
    [desc] 
    FROM [table] 
    GROUP BY itemcode, [desc] 
) 
SELECT * FROM dt WHERE dt.RowNumber = 1 

Est-ce que l'arrêt H8? :)

Ahhh Accès! J'abandonne!

+0

Cela ne fonctionnera pas. 123 Apple 50 fois 123 Apple2 60 fois 001 Orange 20 fois - sélectionnez le top 2 et vous obtenez 2 entrées pour 123 mais aucune pour 001. –

+0

désolé, cela ne fonctionne pas pour moi. – m42

+0

Ah, je vois, d'accord. –

0

Fixé et testé. Il fonctionne comme exsudé - ou mieux comme prévu, car il renvoie toutes les lignes si le nombre le plus élevé pour un ItemCode apparaît plusieurs fois.

SELECT ItemCode, ItemDescription, COUNT(ItemDescription) AS ItemCount 
FROM Items I1 
GROUP BY ItemCode, ItemDescription 
HAVING COUNT(ItemDescription) = 
    (SELECT MAX(ItemCount) 
     FROM (
     SELECT COUNT(ItemDescription) AS ItemCount 
     FROM Items I2 
     WHERE I2.ItemCode = I1.ItemCode 
     GROUP BY ItemDescription 
    ) I3 
    ) 

MISE À JOUR

Juste simplifed la requête un peu.

MISE À JOUR

Impossible de vérifier si cela fonctionne avec Access 2003. tryed, mais l'accès en redemande I1.ItemCode.

+0

toutes les données sont dans une table. (pas réellement appelé table). Cela ne fonctionne pas pour moi. – m42

+2

Malheureusement, cela ne fonctionnera pas avec Jet SQL. Le moteur ne prend pas en charge les sous-requêtes corrélées imbriquées, AFAIR. – Tomalak

+0

Juste testé avec SQL 2005 et je n'utilise pas l'accès, donc je ne peux pas dire si cela fonctionne avec l'accès. –

Questions connexes