一個黑客是使用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個元件向前(對於第n個元素替代2由n)的。
+------------+------------------------------+
| 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使用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的,但可以設置更高)。
更新:上面給出的SQL將給出第n個元素,即使該組中有更少的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子句。只需選擇所有內容並計算出您實際需要的數據庫之外的記錄,最終最簡單。 – 2011-01-26 20:21:47
@Chad Birch。如果我沒有選擇 - 我會按照你的建議去做,但是我覺得這個要求很簡單,而且足夠有用,可以用一個MySql查詢來完成。我可能是錯的,艱難:-) – bavaza 2011-01-27 06:54:49