2010-03-23 2 views
1

Bon, donc celui-ci peut être difficile mais je ferai de mon mieux pour expliquer. Ours avec moi ...Dans mySQL, comment puis-je retourner une liste d'éléments groupés limités à un certain nombre de groupes + éléments uniques

J'ai une table avec plusieurs colonnes comme suit.

ITEM_ID - GROUP_ID
1 - null
2 - null
3 - null
4 - 3
5 - 3
6 - 3
7-21
8-6
9 - 21
10 - 21
11 - 21
12 - 4
13-4
15-6
16-6
17-6
19-3

Je veux aller dans ce tableau et retourner une liste telle que:

1.) Chaque article est séparé.
2.) Chaque élément est groupé par l'ID du groupe.
3.) Le résultat est limité à 5 groupes totaux avec chaque élément qui est compté comme un seul groupe unique.
4.) Lorsqu'un groupe est renvoyé, tous les objets ayant le même numéro de groupe sont renvoyés.

Avec cet exemple, je veux revenir:

1 - null
2 - null
3 - null
4 - 3
5 - 3
6 - 3
19-3
7 - 21
9 - 21
10 - 21
11 - 21

Donc les items 1, 2 et 3 comptent chacun pour 1 groupe retourné par unité pour un total de 3 groupes retournés. Les items 4,5,6 et 19 sont tous du groupe 3 et comptent pour un groupe retourné ce qui porte notre total à 4 groupes retournés. Les items 7, 9, 10 et 11 sont tous du groupe 21 et comptent comme un groupe retourné portant notre total à 5 ​​groupes retournés, point auquel aucun groupe ou élément unique (qui compte comme groupe) n'est renvoyé.

Je suis généralement assez bon avec SQL, mais celui-ci me échappe complètement.

Merci à tous !!!

+0

Bon, alors je continue à travailler dessus et je pourrais avoir quelque chose d'utile. Le code suivant retournera correctement la variable row_counter en triant comme je le veux. set @count: = 0, @group: = ''; SELECT ITEM_ID, GROUP_ID, @count: = IF (@group pas comme GROUP_ID OU GROUP_ID comme "" OU GROUP_ID est nul, @count + 1, @ count) AS row_counter, @group: = GROUP_ID comme dummy FROM ' myTable' ORDER BY GROUP_ID Cela obtient le compte de groupe correctement, mais n'a pas un moyen d'arrêter une fois que la variable row_counter atteint 5. J'ai essayé d'utiliser 'WHERE row_counter <= 5' mais cette erreur. – yesterdayze

+0

D'accord, mes excuses, aucune idée de pourquoi cela n'a pas formaté correctement et ne semble pas vouloir me le formater ... – yesterdayze

+0

Oh, et je ne veux pas utiliser une table temporaire si je peux l'éviter. La requête peut normalement renvoyer des milliers de résultats et est souvent exécutée. Je veux le limiter à l'exécution uniquement sur ce dont il a besoin pour fonctionner. Merci encore! – yesterdayze

Répondre

0

Cela retournera ce que vous demandez. Les sous-requêtes internes filtrent simplement les valeurs nulles et assignent une "clé" unique (un numéro d'identification négatif). Celles-ci sont "limitées" aux cinq premiers ID de groupe uniques et sont ensuite jointes à la copie de la sous-requête pour renvoyer les enregistrements dont nous avons besoin. La sous-requête externe est ensuite utilisée pour imprimer le jeu de résultats de la manière requise.

select a.item_id, case when a.group_id <= 0 then null else a.group_id end group_id 
from (
    select distinct group_id, item_id from test.so_test where group_id is not null 
    union 
    (select -item_id, item_id from test.so_test where group_id is null) 
) a inner join (
    select distinct group_id from test.so_test where group_id is not null 
    union 
    (select -item_id from test.so_test where group_id is null) 
    order by group_id limit 0, 5 
) b on a.group_id = b.group_id 
order by case when a.group_id <= 0 then null else a.group_id end, a.item_id; 
+0

Merci, m'a pris une minute pour voir ce que tu faisais mais une fois j'ai réalisé que j'aurais pu me donner un coup de pied :) Merci beaucoup pour l'aide! – yesterdayze

Questions connexes