2009-03-25 6 views
0

J'ai donc une table d'exemple appelé éléments avec les colonnes suivantes:MySQL: multiples regroupement

  • ITEM_ID (int)
  • person_id (int)
  • item_name (varchar)
  • type_type (varchar) - exemples: "ne ws », "événement", "document"
  • item_date (datetime)

... et une table personne avec les colonnes suivantes: "person_id", "person_name".

J'espérais afficher une liste des deux principaux soumissionnaires (+ le COUNT() des articles soumis) dans une période de temps donnée pour chaque item_type. Voici en gros ce que j'espérais la sortie MySQL ressemblerait à ceci:

person_name | item_type | item_count 

Steve Jobs | document | 11 
Bill Gates | document | 6 
John Doe  | event  | 4 
John Smith | event  | 2 
Bill Jones | news  | 24 
Bill Nye  | news  | 21 

Comment est-ce possible sans faire une requête distincte pour chaque ITEM_TYPE? Merci d'avance!

Répondre

2
SELECT item_type, person_name, item_count 
FROM (
     SELECT item_type, person_name, item_count, 
       @r := IFNULL(@r, 0) + 1 AS rc, 
       CASE WHEN @_item_type IS NULL OR @_item_type <> item_type THEN @r := 0 ELSE 1 END, 
       @_item_type := item_type, 
     FROM (
       SELECT @r := 0, 
         @_item_type := NULL 
       ) vars, 
       (
       SELECT item_type, person_name, COUNT(*) AS item_count 
       FROM items 
       GROUP BY 
         item_type, person_name 
       ORDER BY 
         item_type, person_name, item_count DESC 
       ) vo 
     ) voi 
WHERE rc < 3 
+0

Quelle est l'efficacité plutôt que d'utiliser une requête distincte pour chaque ITEM_TYPE? – Matt

+0

C'est plus efficace. Si vous avez beaucoup de paires (item_type, person_name), c'est même remarquablement efficace. – Quassnoi

+0

Dépend du nombre de types d'objets que vous possédez réellement, mais faire un seul déplacement vers la base de données est normalement une bonne idée, et cette requête semble ne pas être très exigeante sur les ressources. –

1

Je pense que cela devrait le faire:

SELECT person_name,item_type,count(item_id) AS item_count 
FROM person 
LEFT JOIN items USING person_id 
GROUP BY person_id 

La colonne « ITEM_TYPE » va être douteux que, chaque ligne représente plusieurs articles, et vous ne diffusons la ITEM_TYPE de l'un des leur. Vous pouvez tous les lister avec "GROUP_CONCAT", c'est très amusant.

+0

Vous êtes juste en train de regrouper, mais il n'a besoin que des deux premiers soumissionnaires de chaque item_type. – Seb

+0

Ah, je n'ai pas vu la partie sur le top 2 dans chaque catégorie. – GoatRider

1

Quelque chose comme ce travail de Shoul:

SELECT 
    p.person_name, i.item_type, COUNT(1) AS item_count 
FROM 
    person p 
    LEFT JOIN item i 
    ON p.person_id = i.person_id 
GROUP BY 
    p.person_id, 
    i.item_type 
HAVING 
    COUNT(1) >= (
    SELECT 
     COUNT(1) 
    FROM 
     item i2 
    WHERE 
     i2.item_type = i.item_type 
    GROUP BY 
     i2.person_id 
    LIMIT 1,1 
) 
+0

ne fonctionne pas: pour certains types d'événement, renvoie seulement 1 émetteur supérieur même s'il y en a plus pour ce type. –