Una trucco è quello di utilizzare group_concat. Raggruppa per data e concat la data di scadenza in ordine crescente e utilizza la funzione substring_index per recuperare il valore n.
mysql> select * from expiry;
+------------+------------+
| date | expiry |
+------------+------------+
| 2010-01-01 | 2010-02-01 |
| 2010-01-01 | 2010-03-02 |
| 2010-01-01 | 2010-04-04 |
| 2010-02-01 | 2010-03-01 |
| 2010-02-01 | 2010-04-02 |
+------------+------------+
5 rows in set (0.00 sec)
mysql> SELECT mdate,
Substring_index(Substring_index(edate, ',', 2), ',', -1) AS exp_date
FROM (SELECT `date` AS mdate,
GROUP_CONCAT(expiry order by expiry asc separator ",") AS edate
FROM expiry
GROUP BY mdate) e1;
+------------+------------+
| mdate | exp_date |
+------------+------------+
| 2010-01-01 | 2010-03-02 |
| 2010-02-01 | 2010-04-02 |
+------------+------------+
2 rows in set (0.00 sec)
Nell'esempio qui il sub-query pronunciato la seguente output:
+------------+----------------------------------+
| mdate | edate |
+------------+----------------------------------+
| 2010-01-01 | 2010-02-01,2010-03-02,2010-04-04 |
| 2010-02-01 | 2010-03-01,2010-04-02 |
+------------+----------------------------------+
substring_index (EDATE, '', 2) va 2 elementi in avanti (per ennesimo elemento sostitutivo 2 per n) .
+------------+------------------------------+
| mdate | substring_index(edate,',',2) |
+------------+------------------------------+
| 2010-01-01 | 2010-02-01,2010-03-02 |
| 2010-02-01 | 2010-03-01,2010-04-02 |
+------------+------------------------------+
corriamo un'altra substring_index sull'uscita sopra per ottenere solo il 2 ° elemento (l'ultimo elemento del risultato intermedio) utilizzando substring_index (substring_index (EDATE, '', 2), '', - 1)
+------------+------------------------------------------------------+
| mdate | substring_index(substring_index(edate,',',2),',',-1) |
+------------+------------------------------------------------------+
| 2010-01-01 | 2010-03-02 |
| 2010-02-01 | 2010-04-02 |
+------------+------------------------------------------------------+
Se ci sono troppi valori per concat si potrebbe correre su value group_concat_max_len (default 1024, ma può essere impostato più alto).
AGGIORNAMENTO: L'SQL sopra riportato fornisce l'ennesimo elemento anche quando sono presenti meno n elementi per il gruppo. Per evitare che sql possa essere modificato come:
SELECT mdate,
IF(cnt >= 2,Substring_index(Substring_index(edate, ',', 2), ',', -1),NULL) AS exp_date
FROM (SELECT `date` AS mdate,
count(expiry) as cnt,
GROUP_CONCAT(expiry order by expiry asc separator ",") AS edate
FROM expiry
GROUP BY mdate) e1;
È necessario eseguire assolutamente all'interno di una singola query? È particolarmente difficile perché MySQL non supporta le clausole 'LIMIT' all'interno delle sottoquery. Potrebbe essere più semplice selezionare tutto e calcolare il record che si desidera al di fuori del database. –
@Chad Birch. Se non ho scelta, farò come suggerito, ma ritengo che il requisito sia abbastanza semplice e utile per poterlo fare con una sola query MySql. Potrei sbagliarmi, difficile :-) – bavaza
Contrassegnato con "greatest-n-per-group".Alcune delle risposte hanno un modo generale di gestire questa caratteristica mancante in MySQL usando trucchi intelligenti; quelli che generano un gruppo completo dovrebbero essere selezionabili. Buona fortuna a trovare il codice magico. –