Comment sélectionner la première ligne de chaque groupe dans MySQL?
En C#, il serait comme ceci:
table
.GroupBy(row => row.SomeColumn)
.Select(group => group
.OrderBy(row => row.AnotherColumn)
.First()
)
Linq-to-Sql traduit le code T-SQL suivant:
SELECT [t3].[AnotherColumn], [t3].[SomeColumn]
FROM (
SELECT [t0].[SomeColumn]
FROM [Table] AS [t0]
GROUP BY [t0].[SomeColumn]
) AS [t1]
OUTER APPLY (
SELECT TOP (1) [t2].[AnotherColumn], [t2].[SomeColumn]
FROM [Table] AS [t2]
WHERE (([t1].[SomeColumn] IS NULL) AND ([t2].[SomeColumn] IS NULL))
OR (([t1].[SomeColumn] IS NOT NULL) AND ([t2].[SomeColumn] IS NOT NULL)
AND ([t1].[SomeColumn] = [t2].[SomeColumn]))
ORDER BY [t2].[AnotherColumn]
) AS [t3]
ORDER BY [t3].[AnotherColumn]
Mais il est incompatible avec MySQL.
- ne pouvez-vous pas surveiller le serveur de base de données pour voir ce que les requêtes de C# exécute (je suis certains-ce qui suppose que votre syntaxe ci-dessus est LINQ)
- Oui, je peux, et je l'ai fait avec MS SQL Server. Mais je n'ai pas de Linq-to-MySQL, seulement Linq-to-Sql
Vous devez vous connecter pour publier un commentaire.
J'ai basé ma réponse sur le titre de votre post seulement, comme je ne sais pas C# et ne comprend pas la requête donnée. Mais dans MySQL, je vous suggère d'essayer les sous-sélections. De la première à obtenir un ensemble de clés primaires de intéressant de colonnes, sélectionnez les données à partir de ces lignes:
id
pour ma table.Quand j'écris
Il fonctionne. IIRC dans d'autres SGBDR une telle déclaration est impossible, car une colonne qui n'appartient pas à la groupement de la clé est d'être référencé, sans aucune sorte d'agrégation.
Cette "bizarrerie" se comporte de très près à ce que je veux. Je l'ai donc utilisé pour obtenir le résultat que je voulais:
Voici une autre façon vous pourriez essayer, qui n'a pas besoin que le champ ID.
Encore je suis d'accord avec lfagundes que vous devez ajouter une clé primaire ..
Aussi méfiez-vous qu'en faisant cela, vous ne pouvez pas (facilement) obtenir à l'autre des valeurs est la même ligne que le some_colum, another_column paire! Vous auriez besoin de lfagundes apprach et un penalty pour le faire!
Vous devrait utiliser une fonction d'agrégation pour obtenir la valeur de AnotherColumn que vous voulez. C'est, si vous voulez la valeur la plus basse de AnotherColumn pour chaque valeur de SomeColumn (qu'elle soit numérique ou de manière lexicographique), vous pouvez utiliser:
Espérons que certains liens utiles:
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
http://www.oreillynet.com/databases/blog/2007/05/debunking_group_by_myths.html
MIN
maisFIRST
, qui MySQL manque.De MySQL 5.7 documentation
Cela signifie que @Jader Dias solution ne fonctionne pas partout.
Voici une solution qui pourrait fonctionner quand
ONLY_FULL_GROUP_BY
est activé:Je n'ai pas vu la solution suivante parmi les réponses, alors j'ai pensé que je l'avais mis là-bas.
Le problème est de sélectionner des lignes, qui sont les premières lignes lorsque commandés par
AnotherColumn
dans tous les groupes regroupés parSomeColumn
.La solution suivante le faire dans MySQL.
id
doit être une colonne unique qui ne doit pas contenir des valeurs contenant-
(que j'ai utiliser comme séparateur).Il y a un demande de fonctionnalité pour
FIRST()
etLAST()
dans la base de données MySQL bug tracker, mais il a été fermé il y a plusieurs années.Encore une autre façon de faire (sans la clé primaire) serait d'utiliser le JSON fonctions:
ou pré 5.7.22
De commande (ou filtrage) peut être fait avant de groupement:
... ou après regroupement (bien sûr):
Certes, c'est plutôt alambiqué et de la performance est probablement pas très importante (ne pas le tester sur des données de grande taille, fonctionne bien sur mon limitée des ensembles de données).
Avec MySQL v8+ vous pouvez utiliser les fonctions de la fenêtre
Encore une autre façon de faire
Select max de groupe qui travaille dans les vues
Comment à ce sujet:
Pourquoi ne pas utiliser MySQL LIMITE de mot-clé?