Один хак использовать GROUP_CONCAT. Группируйте по дате и укажите дату истечения срока в порядке возрастания и используйте функцию substring_index для получения 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)
В примере здесь суб-запрос дает следующий результат:
+------------+----------------------------------+
| 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) проходит 2 элемента вперед (для п-го элемента замены 2 на п) ,
+------------+------------------------------+
| mdate | substring_index(edate,',',2) |
+------------+------------------------------+
| 2010-01-01 | 2010-02-01,2010-03-02 |
| 2010-02-01 | 2010-03-01,2010-04-02 |
+------------+------------------------------+
мы запустим еще SUBSTRING_INDEX на выводе выше, чтобы получить только 2-й элемент (последний элемент промежуточного результата) с использованием 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 |
+------------+------------------------------------------------------+
Если есть слишком много значений для Concat вы можете запустить из group_concat_max_len значения (по умолчанию 1024, но могут быть установлены выше).
UPDATE: SQL, приведенный выше, даст n-й элемент, даже если для группы th меньше n элементов. Чтобы избежать этого, sql может быть изменен как:
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;
Абсолютно необходимо выполнить внутри одного запроса? Это особенно сложно, потому что MySQL не поддерживает предложения 'LIMIT' внутри подзапросов. Это может оказаться самым простым, просто выбрать все и разработать, какую запись вы действительно хотите за пределами базы данных. –
@Chad Birch. Если у меня нет выбора - я сделаю то, что вы предложили, но я считаю, что это требование просто и полезно для меня, чтобы иметь возможность сделать это с помощью одного запроса MySql. Возможно, я ошибаюсь, жестко :-) – bavaza
С меткой «наибольший-на-группу».В некоторых ответах есть общий способ справиться с этой недостающей функцией в MySQL, используя умные трюки; те, которые генерируют полный набор групп, должны выбираться против. Удачи в поиске магического кода. –