web-dev-qa-db-fra.com

Sélectionnez une colonne distincte avec d'autres colonnes dans MySQL

Je n'arrive pas à trouver une solution appropriée pour le problème suivant (probablement vieux), en espérant que quelqu'un puisse faire la lumière. J'ai besoin de retourner 1 colonne distincte avec d'autres colonnes non distinctes dans mySQL.

J'ai le tableau suivant dans mySQL:

id      name       destination     rating     country
----------------------------------------------------
1       James      Barbados        5          WI
2       Andrew     Antigua         6          WI
3       James      Barbados        3          WI
4       Declan     Trinidad        2          WI
5       Steve      Barbados        4          WI
6       Declan     Trinidad        3          WI

Je voudrais que l'instruction SQL renvoie le nom DISTINCT avec la destination, la notation basée sur le pays.

id      name       destination     rating     country
----------------------------------------------------
1       James      Barbados        5          WI
2       Andrew     Antigua         6          WI
4       Declan     Trinidad        2          WI
5       Steve      Barbados        4          WI

Comme vous pouvez le voir, James et Declan ont des notes différentes, mais le même nom, ils ne sont donc retournés qu'une seule fois.

La requête suivante renvoie toutes les lignes car les notes sont différentes. Puis-je de toute façon retourner le jeu de résultats ci-dessus?

SELECT (distinct name), destination, rating 
  FROM table 
 WHERE country = 'WI' 
 ORDER BY id
28
user1038814

En utilisant une sous-requête, vous pouvez obtenir le id le plus élevé pour chaque nom, puis sélectionner le reste des lignes en fonction de cela:

SELECT * FROM table
WHERE id IN (
  SELECT MAX(id) FROM table GROUP BY name
)

Si vous préférez, utilisez MIN(id) pour obtenir le premier enregistrement de chaque nom au lieu du dernier.

Cela peut également être fait avec un INNER JOIN Contre la sous-requête. À cet effet, les performances doivent être similaires, et parfois vous devez joindre sur deux colonnes de la sous-requête.

SELECT
  table.*
FROM 
  table
  INNER JOIN (
    SELECT MAX(id) AS id FROM table GROUP BY name
  ) maxid ON table.id = maxid.id
25
Michael Berkowski

Le problème est que des œuvres distinctes s'appliquent à l'ensemble des retours et pas seulement au premier champ. Sinon, MySQL ne saurait pas quel enregistrement renvoyer. Donc, vous voulez avoir une sorte de fonction de groupe sur l'évaluation, que ce soit MAX, MIN, GROUP_CONCAT, AVG ou plusieurs autres fonctions.

Michael a déjà posté une bonne réponse, donc je ne vais pas réécrire la requête.

4
Brian Hoover

Vous pouvez faire un group by:

select min(id) as id, name, destination, avg(rating) as rating, country from TABLE_NAME group by name, destination, country
3
Ricardo Souza

Je suis d'accord avec @rcdmk. L'utilisation d'une sous-requête DEPENDENT peut réduire les performances, GROUP BY semble plus approprié à condition que vous ayez déjà INDEXÉ le pays et seules quelques lignes atteindront le serveur. En réécrivant la requête giben par @rcdmk, j'ai ajouté le COMMANDER PAR NULL pour supprimer l'ordre implicite de GROUP BY, pour le rendre un peu plus rapide:

SELECT MIN(id) as id, name, destination as rating, country 
FROM table WHERE country = 'WI' 
GROUP BY name, destination ORDER BY NULL
2
wisefish