In C # wäre es so:
table
.GroupBy(row => row.SomeColumn)
.Select(group => group
.OrderBy(row => row.AnotherColumn)
.First()
)
Linq-To-Sql übersetzt es in den folgenden T-SQL-Code:
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]
Es ist jedoch nicht mit MySQL kompatibel.
Antworten:
Ich habe meine Antwort nur auf den Titel Ihres Beitrags gestützt, da ich C # nicht kenne und die angegebene Abfrage nicht verstanden habe. Aber in MySQL empfehle ich Ihnen, Unterauswahlen zu versuchen. Holen Sie sich zuerst einen Satz Primärschlüssel mit interessanten Spalten und wählen Sie dann Daten aus diesen Zeilen aus:
SELECT somecolumn, anothercolumn FROM sometable WHERE id IN ( SELECT min(id) FROM sometable GROUP BY somecolumn );
quelle
id
für meine Tabelle erstelle .Wenn ich schreibe
SELECT AnotherColumn FROM Table GROUP BY SomeColumn ;
Es klappt. IIRC in anderen RDBMS ist eine solche Anweisung nicht möglich, da auf eine Spalte, die nicht zum Gruppierungsschlüssel gehört, ohne irgendeine Art von Aggregation verwiesen wird.
Diese "Eigenart" verhält sich sehr genau so, wie ich es will. Also habe ich es benutzt, um das gewünschte Ergebnis zu erzielen:
SELECT * FROM ( SELECT * FROM `table` ORDER BY AnotherColumn ) t1 GROUP BY SomeColumn ;
quelle
Hier ist eine andere Möglichkeit, die Sie versuchen könnten, ohne dieses ID-Feld zu benötigen.
select some_column, min(another_column) from i_have_a_table group by some_column
Trotzdem stimme ich lfagundes zu, dass Sie einen Primärschlüssel hinzufügen sollten.
Beachten Sie auch, dass Sie auf diese Weise nicht (leicht) zu den anderen Werten gelangen können, die dieselbe Zeile wie das resultierende Paar some_colum, another_column sind! Dafür brauchst du lfagundes apprach und eine PK!
quelle
SELECT t1.* FROM table_name AS t1 LEFT JOIN table_name AS t2 ON ( t2.group_by_column = t1.group_by_column -- group_by_column is the column you would use in the GROUP BY statement AND t2.order_by_column < t1.order_by_column -- order_by_column is column you would use in the ORDER BY statement -- usually is the autoincremented key column ) WHERE t2.group_by_column IS NULL;
Mit MySQL v8 + können Sie Fensterfunktionen verwenden
quelle
ONLY_FULL_GROUP_BY
aktiviertem Gerät für meinen Anwendungsfall arbeiten konnte. Wir haben eine PK eingerichtet und aus irgendeinem Grund dachte MySQL 5.7 immer wieder, dass dies nicht funktional von der Spalte abhängt, die wir benötigenGROUP BY
. Die anderen Antworten scheinen sehr spezifisch für das jeweilige Problem zu sein oder erfordern SQL-Variablen ... Dies ist eine direkte Abfrage, die für viele Zwecke allgemein genug ist. Das einzige, was ich ändern musste, war die Ungleichheit für dieORDER BY
Spalten, aber das ist je nach Bedarf zu erwarten.Sie sollten eine Aggregatfunktion verwenden, um den gewünschten Wert von AnotherColumn abzurufen. Wenn Sie also den niedrigsten Wert von AnotherColumn für jeden Wert von SomeColumn (entweder numerisch oder lexikografisch) möchten, können Sie Folgendes verwenden:
SELECT SomeColumn, MIN(AnotherColumn) FROM YourTable GROUP BY SomeColumn
Einige hoffentlich hilfreiche Links:
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
quelle
MIN
aber nichtFIRST
, was MySQL fehlt.Aus der MySQL 5.7-Dokumentation
Dies bedeutet, dass die Lösung von @Jader Dias nicht überall funktionieren würde.
Hier ist eine Lösung, die funktionieren würde, wenn sie
ONLY_FULL_GROUP_BY
aktiviert ist:SET @row := NULL; SELECT SomeColumn, AnotherColumn FROM ( SELECT CASE @id <=> SomeColumn AND @row IS NOT NULL WHEN TRUE THEN @row := @row+1 ELSE @row := 0 END AS rownum, @id := SomeColumn AS SomeColumn, AnotherColumn FROM SomeTable ORDER BY SomeColumn, -AnotherColumn DESC ) _values WHERE rownum = 0 ORDER BY SomeColumn;
quelle
Ich habe die folgende Lösung unter den Antworten nicht gesehen, also dachte ich, ich würde sie dort veröffentlichen.
Das Problem besteht darin, Zeilen auszuwählen, die die ersten Zeilen sind, wenn sie
AnotherColumn
in allen nach gruppierten Gruppen sortiert sindSomeColumn
.Die folgende Lösung erledigt dies in MySQL.
id
muss eine eindeutige Spalte sein, die keine enthaltenden Werte enthalten darf-
(die ich als Trennzeichen verwende).select t1.* from mytable t1 inner join ( select SUBSTRING_INDEX( GROUP_CONCAT(t3.id ORDER BY t3.AnotherColumn DESC SEPARATOR '-'), '-', 1 ) as id from mytable t3 group by t3.SomeColumn ) t2 on t2.id = t1.id -- Where SUBSTRING_INDEX(GROUP_CONCAT(id order by AnotherColumn desc separator '-'), '-', 1) -- can be seen as: FIRST(id order by AnotherColumn desc) -- For completeness sake: SUBSTRING_INDEX(GROUP_CONCAT(id order by AnotherColumn desc separator '-'), '-', -1) -- would then be seen as: LAST(id order by AnotherColumn desc)
Es gibt eine Funktionsanforderung für
FIRST()
undLAST()
im MySQL-Bug-Tracker, die jedoch vor vielen Jahren geschlossen wurde.quelle
Beste Leistung und einfach zu bedienen:
SELECT id, code, SUBSTRING_INDEX( GROUP_CONCAT(price ORDER BY id DESC), ',', 1) first_found_price FROM stocks GROUP BY code ORDER BY id DESC
quelle
Ich schlage vor, diesen offiziellen Weg von MySql zu verwenden:
SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article GROUP BY s2.article) ORDER BY article;
Auf diese Weise können wir den höchsten Preis für jeden Artikel erzielen
quelle
Wie wäre es damit:
SELECT SUBSTRING_INDEX( MIN(CONCAT(OrderColumn, '|', IFNULL(TargetColumn, '')) ), '|', -1) as TargetColumn FROM table GROUP BY GroupColumn
quelle
Eine weitere Möglichkeit (ohne Primärschlüssel) wäre die Verwendung der JSON-Funktionen:
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") ) from sometable group by somecolumn
oder vor 5.7.22
select somecolumn, json_unquote( json_extract( concat('["', group_concat(othercolumn separator '","') ,'"]') ,"$[0]" ) ) from sometable group by somecolumn
Die Bestellung (oder Filterung) kann vor der Gruppierung erfolgen:
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") ) from (select * from sometable order by othercolumn) as t group by somecolumn
... oder nach der Gruppierung (natürlich):
select somecolumn, json_unquote( json_extract(json_arrayagg(othercolumn), "$[0]") ) as other from sometable group by somecolumn order by other
Zugegeben, es ist ziemlich kompliziert und die Leistung ist wahrscheinlich nicht großartig (hat es nicht mit großen Datenmengen getestet, funktioniert gut mit meinen begrenzten Datenmengen).
quelle
Noch ein anderer Weg, es zu tun
Wählen Sie max aus der Gruppe aus, die in Ansichten funktioniert
SELECT * FROM action a WHERE NOT EXISTS ( SELECT 1 FROM action a2 WHERE a2.user_id = a.user_id AND a2.action_date > a.action_date AND a2.action_type = a.action_type ) AND a.action_type = "CF"
quelle
Wählen Sie die erste Zeile für jede Gruppe (wie in einer Spalte geordnet) in MySQL aus.
Wir haben:
eine Tabelle: mytable
eine Spalte, nach der wir bestellen: the_column_to_order_by
eine Spalte, nach der wir gruppieren möchten: the_group_by_column
Hier ist meine Lösung. Mit der inneren Abfrage erhalten Sie einen eindeutigen Satz von Zeilen, die als Doppelschlüssel ausgewählt sind. Die äußere Abfrage verbindet dieselbe Tabelle, indem beide Schlüssel (mit UND) verknüpft werden.
SELECT * FROM ( SELECT the_group_by_column, MAX(the_column_to_order_by) the_column_to_order_by FROM mytable GROUP BY the_group_by_column ORDER BY MAX(the_column_to_order_by) DESC ) as mytable1 JOIN mytable mytable2 ON mytable2.the_group_by_column = mytablealiamytable2.the_group_by_column AND mytable2.the_column_to_order_by = mytable1.the_column_to_order_by;
Zu Ihrer Information: Ich habe überhaupt nicht an Effizienz gedacht und kann auf die eine oder andere Weise nicht mit ihr sprechen.
quelle
Warum nicht das Schlüsselwort MySQL LIMIT verwenden?
SELECT [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] LIMIT 1
quelle