8
votes

Comment sélectionner un nombre fixe de lignes pour chaque groupe?

Voici quelques exemples de données dans une table MySQL

   a    b   distance
    30  41  250
    95  18  250
    59  25  500
    65  85  500
    15  57  750
    89  35  750
    79  22  1000
    98  41  1000


0 commentaires

3 Réponses :


7
votes

Utilisation:

SELECT x.a,
       x.b,
       x.distance
  FROM (SELECT t.a,
               t.b,
               t.distance
               CASE 
                 WHEN @distance != t.distance THEN @rownum := 1 
                 ELSE @rownum := @rownum + 1 
               END AS rank,
               @distance := t.distance
          FROM TABLE t
          JOIN (SELECT @rownum := 0, @distance := '') r
      ORDER BY t.distance --important for resetting the rownum variable) x
 WHERE x.rank <= 2
ORDER BY x.distance, x.a


5 commentaires

C'est souvent une éducation lisant vos réponses. Comment les lignes sont-elles sélectionnées aléatoires?


@MDMA: Les lignes sont classées de manière aléatoire car elles sont commandées uniquement par la valeur de distance - toute paire de valeur A & B peut être classée comme 1, etc. Le commander par T.Distance est juste pour garder Les valeurs de distance regroupées, la déclaration de cas réinitialise correctement la valeur ROWNUM pour démarrer à 1 lorsqu'une nouvelle valeur de distance est rencontrée.


Merci pour la clarification. Cela ne signifie pas que les lignes sélectionnées sont arbitraires plutôt que aléatoires. (C'est-à-dire qu'ils pourraient être les mêmes chaque fois que la requête est courante?)


@MDMA: Commander par la colonne de distance ne garantit que les mêmes valeurs A et B seront toujours renvoyées à la même position. Et être aléatoire ne garantit pas que différentes valeurs seront toujours retournées.


@Omgponies: ne devrait-il pas le @Distance = to.distance être un @DISTANCE: = T.DISTANCE à la place?



0
votes

Un moyen serait d'utiliser Union. Comme:

(SELECT a, b, distance FROM table WHERE distance = 250 LIMIT 2 ORDER BY RAND())
UNION
(SELECT a, b, distance FROM table WHERE distance = 500 LIMIT 2 ORDER BY RAND())
...
ORDER BY distance


1 commentaires

En utilisant Union tout serait mieux, voyant qu'il n'y aurait pas de duplicats à être supprimés. En outre, commander par rand () ne fonctionne pas bien: Stackoverflow.com/Questtions/1823306/...



0
votes

Je me demande si cela fonctionnera? XXX

EDIT: Malheureusement pas. La limite n'est pas prise en charge dans une sous-requête.


0 commentaires