mysql分段排序

longerandlonger發表於2012-11-01

需求:

一個活動表,記錄有開始時間欄位start_time,結束時間欄位end_time

需要分頁獲取全部欄位,總體上:

  • 1.正在進行的活動排在最前部分(start_time < now < end_time)

這部分內部,按結束時間升敘,也就是即將結束的活動在前面。

  • 2.即將開始的活動排在中間部分(now < start_time);

這部分內部,按開始時間升序,也就是即將開始的活動在前面。

  • 3.已經過期的活動在最後部分(end_time < now)。

這部分內部,按結束時間降序,也就是最近結束的活動在前面。


分析:

根據條件,將(開始時間,結束時間)對映到一個整數序列,然後根據這個序列排序。

我找到的對映是這樣的:

首先確認一個“很大的數”Big。由於資料庫的時間範圍在1970-01-01 ~ 2038-01-19之間,值小於pow(2, 31),所以我確定的“很大的數”是Big=pow(2, 40);

對映

f(start_time, end_time)

{

    if (start_time < now < end_time) 

    {

        return  end_time;

    }

    else if (now < start_time)

    {

        return start_time + pow(2, 40);

    }

    else if (end_time < now)

    {

        return (-1)*end_time + pow(2,41);

    }

}

自己證明:end_time  <  start_time + pow(2, 40)  <  (-1)*end_time + pow(2,41)

然後,寫出的sql語句是:

SELECT id, start_time, end_time FROM lj_activity WHERE STATUS = 0 ORDER BY
	IF (UNIX_TIMESTAMP(start_time)<=UNIX_TIMESTAMP(NOW()) AND UNIX_TIMESTAMP(NOW())<UNIX_TIMESTAMP(end_time),
		UNIX_TIMESTAMP(end_time),
		IF(UNIX_TIMESTAMP(NOW())<UNIX_TIMESTAMP(start_time),
			UNIX_TIMESTAMP(start_time)+POW(2,40),
			UNIX_TIMESTAMP(end_time)*(-1)+POW(2,41)
		)
	);



相關文章