1
votes

Comment sélectionner les plus grandes lignes de chaque type

J'ai une table avec PK ("object", "type", "mid") et cette structure:

+-----+----------+-------+---------+-----+
| type|  object  | value | preview | mid |
+-----+----------+-------+---------+-----+
| t1  | uid-0002 |   10  | p2      | 1   |
| t2  | uid-0003 |   5   | p3      | 1   |
| t3  | uid-0005 |   10  | p5      | 2   |
| t4  | uid-0004 |   5   | p4      | 2   |
+-----+----------+-------+---------+-----+

Le résultat que je voudrais obtenir est:

SELECT * 
FROM (SELECT * FROM table ORDER BY value desc) x 
GROUP BY type;

Le SQL que j'ai essayé est:

SELECT * 
FROM table 
WHERE value in (SELECT max(value) FROM table GROUP BY type) 
GROUP BY type

Mais cela échoue car il obtient une valeur incorrecte quand c'est plus d'un identique valeur dans le tableau.

J'ai aussi essayé

+-----+----------+-------+---------+-----+
| type|  object  | value | preview | mid |
+-----+----------+-------+---------+-----+
| t1  | uid-0002 |   10  | p2      | 1   |
| t2  | uid-0003 |   5   | p3      | 1   |
| t3  | uid-0001 |   40  | p1      | 2   |
| t4  | uid-0004 |   5   | p4      | 2   |
+-----+----------+-------+---------+-----+

mais il y a la même erreur.

Exemple de résultats incorrects: p>

+-----+----------+-------+---------+-----+
| type|  object  | value | preview | mid |
+-----+----------+-------+---------+-----+
| t1  | uid-0001 |   2   | p1      | 1   |
| t1  | uid-0002 |   10  | p2      | 1   |
| t2  | uid-0001 |   1   | p1      | 1   |
| t2  | uid-0003 |   5   | p3      | 1   |
| t3  | uid-0005 |   10  | p5      | 2   |
| t3  | uid-0001 |   40  | p1      | 2   |
| t4  | uid-0004 |   5   | p4      | 2   |
+-----+----------+-------+---------+-----+

Dans ce cas, les lignes pour t3 et t1 ont utilisé la même valeur (10, qui doit être pour t1) et l'ont sélectionnée dans les deux types (t1, t3);


0 commentaires

3 Réponses :


1
votes

Votre première tentative est vraiment proche, il vous suffit d'ajouter une clause where à votre sous-requête pour la lier à la requête externe, plutôt que d'utiliser GROUP BY , ce qui suit obtiendra les résultats souhaités:

SELECT t.Type, t.Object, t.Value, t.Preview
FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Value DESC) AS rowNumber
      FROM Table) AS t
WHERE t.RowNumber = 1
ORDER BY t.Type;

Exemple sur SQL Fiddle

Si vous utilisez une version plus récente de MySQL (8.0), vous pouvez également utiliser ROW_NUMBER () :

SELECT t.Type, t.Object, t.Value, t.Preview 
FROM Table AS t
WHERE value IN (SELECT max(value) FROM Table AS t2 WHERE t2.Type = t.Type) 
ORDER BY t.Type;

Exemple sur DB Fiddle


1 commentaires

Merci! il m'a aidé, mais pour l'instant je ne peux pas vous ajouter + représentant. Je reviendrai quand j'aurai 15 ans.



1
votes

Vous pouvez créer une table avec uniquement le type et la valeur maximale pour chaque type, puis utiliser cette table comme filtre pour voir uniquement les enregistrements avec la valeur maximale

SELECT *
FROM table t
JOIN (
    SELECT
        type
        ,MAX(value) as max_value
    FROM table
    ) m on t.type = m.type and t.value = m.max_value


0 commentaires

0
votes

Vous pouvez utiliser la requête ci-dessous pour trouver la solution optimale et vous assurer que le type de données de la colonne "Valeur" doit être "Nombre".

 SELECT * FROM table WHERE (type,VALUE) IN (SELECT type,MAX(value) FROM table GROUP BY type) 


2 commentaires

A un doublon en raison d'avoir les mêmes valeurs dans le champ de valeur


Vous ne rencontrerez aucun problème en cas de mêmes valeurs dans le champ de valeur.