Sie könnten verwenden GROUP_CONCAT aggregiert Funktion , um alle Jahre in einer einzigen Spalte zu erhalten, gruppiert nach id
und geordnet nach rate
:
SELECT id, GROUP_CONCAT(year ORDER BY rate DESC) grouped_year
FROM yourtable
GROUP BY id
Ergebnis:
-----------------------------------------------------------
| ID | GROUPED_YEAR |
-----------------------------------------------------------
| p01 | 2006,2003,2008,2001,2007,2009,2002,2004,2005,2000 |
| p02 | 2001,2004,2002,2003,2000,2006,2007 |
-----------------------------------------------------------
Und dann könnten Sie FIND_IN_SET verwenden , das die Position des ersten Arguments innerhalb des zweiten zurückgibt, z.
SELECT FIND_IN_SET('2006', '2006,2003,2008,2001,2007,2009,2002,2004,2005,2000');
1
SELECT FIND_IN_SET('2009', '2006,2003,2008,2001,2007,2009,2002,2004,2005,2000');
6
Mit einer Kombination aus GROUP_CONCAT
und FIND_IN_SET
und Filtern nach der von find_in_set zurückgegebenen Position können Sie dann diese Abfrage verwenden, die nur die ersten 5 Jahre für jede ID zurückgibt:
SELECT
yourtable.*
FROM
yourtable INNER JOIN (
SELECT
id,
GROUP_CONCAT(year ORDER BY rate DESC) grouped_year
FROM
yourtable
GROUP BY id) group_max
ON yourtable.id = group_max.id
AND FIND_IN_SET(year, grouped_year) BETWEEN 1 AND 5
ORDER BY
yourtable.id, yourtable.year DESC;
Bitte sehen Sie Geige hier .
Beachten Sie, dass Sie, wenn mehr als eine Zeile dieselbe Rate haben kann, die Verwendung von GROUP_CONCAT (DISTINCT rate ORDER BY rate) in der Tarifspalte anstelle der Jahresspalte in Betracht ziehen sollten.
Die maximale Länge der von GROUP_CONCAT zurückgegebenen Zeichenfolge ist begrenzt. Dies funktioniert daher gut, wenn Sie für jede Gruppe einige Datensätze auswählen müssen.
LIMIT
Klausel. Hier ist ein Artikel, der das Problem ausführlich erklärt: So wählen Sie die erste / kleinste / maximale Zeile pro Gruppe in SQL aus Es ist ein guter Artikel - er führt eine elegante, aber naive Lösung für das Problem "Top N pro Gruppe" ein und dann schrittweise verbessert es.