2016-03-28 67 views
3

我已經有了這個SQL查詢;根據日期顯示5個數據庫條目

SELECT * FROM `articles` WHERE 
`type` = 'press' AND (`published` = '1' AND `time_start` >= '".$time_today."') 
ORDER BY `time_start` ASC, `id` DESC LIMIT 5 

這個想法是總是顯示5篇文章。 time_start是開始時間,time_end是結束時間(只是PHP的mktime)。

這些文章基本上是日曆條目,只有從明天開始的條目應該顯示(工作),並且只有第一個即將到來的五個。目前,即將到來的日曆點數不到五個。

我該如何基本上讓它做這個查詢if num_rows > 5, else fill up with older ones?我應該看看一個PHP fallback簡單地用不同的查詢覆蓋數據(顯示5個'最新'文章)還是有一種方法可以在查詢本身中工作?

問題是沒有那麼多關於它如何能做到爲尋找正確的方式做到這一點,希望這不是違反規定

+0

使用此ORDER BY'time_start' DESC,'id' DESC LIMIT 0,5 –

回答

1

因此,它看起來像你想從開始時間開始5個事件的窗口..它顯示在即將到來的情況下,以前的事件。

兩個可行的方案,在這裏..

如果你很高興處理這個應用程序中的邏輯:

運行:

SELECT * 
    FROM articles 
    WHERE type = press 
    AND published = '1' 
    AND time_start >= :time_today 
ORDER BY time_start ASC, id ASC /* 'I thought id should be ascending here */ 
    LIMIT 5 

計算出有多少額外的文章,你仍然需要和然後運行:

SELECT * 
    FROM articles 
    WHERE type = press 
    AND published = '1' 
    AND time_start < :time_today 
ORDER BY time_start DESC, id DESC 
    LIMIT :slack 

簡單地顛倒第一個結果集並追加第二個結果集並繼續前進。

如果你想做到這一切在DB我可能會做的事:

SELECT * 
    FROM ((
     SELECT * 
     FROM articles 
     WHERE type = press 
     AND published = '1' 
     AND time_start >= :time_today 
    ORDER BY time_start ASC, id ASC 
     LIMIT 5 
      ) 
    UNION ALL 
      (
     SELECT * 
     FROM articles 
     WHERE type = press 
     AND published = '1' 
     AND time_start < :time_today 
    ORDER BY time_start DESC, id DESC 
     LIMIT 5 
     )) window_extents 
ORDER BY time_start DESC, id DESC 
    LIMIT 5 

這是通過選擇所有可能的記錄窗口,然後縮小的結果。它也應該很好地利用你的索引。

N.B.它看起來像你將日期轉換爲查詢而不是綁定在..我會擺脫這樣做的習慣,即使在安全的環境中,除非絕對必要。

0

簡單地爲了通過TIME_START,然後做5 限制所以,你肯定會得到5個沒有排,並根據時間大於你在條件中指定的時間。

(只要你有5項的任何時間所提供的時間後)

+0

這裏的問題是它需要顯示'現在'的第一個和之後的4。這個想法是,將會有大約40-50個不同的項目排列在總覽中,但這些項目與FrontPage中突出顯示的項目不相關。 – Ieuan

0
SELECT date1, 
    IF((unix_timestamp(date1) - unix_timestamp()) > 0, 1, 0) as a, 
    IF((unix_timestamp(date1) - unix_timestamp()) > 0, (unix_timestamp(date1) - unix_timestamp())/10000000, unix_timestamp(date1) - unix_timestamp()) as b 
FROM `test1` WHERE 1 order by a desc, b desc limit 0,5 

你應該用PHP替代查詢去,但如果你願意,你可以使用這樣的事情。 TS說,如果日期在將來,我們將它分成一個大的數字以保持它接近0,以便我們可以比較/優先考慮來自TS的過去。我知道這很醜陋,但醜陋很有趣。你必須添加你測試並用$ my_now_timestamp替換unix_timestamp(),並在測試中添加一些性能條件,以避免解析所有表...

0

只是刪除從where子句(AND TIME_START >= '".$time_today."'),你必須通過部分類似下面的查詢

SELECT * 
FROM `articles` 
WHERE `type` = 'press' 
    AND `published` = '1' 
ORDER BY 
    CASE WHEN `time_start` >= '".$time_today."' 
     THEN 0 ELSE 1 END ASC, 
    CASE WHEN `time_start` >= '".$time_today."' 
     THEN `time_start` END ASC, 
    CASE WHEN `time_start` < '".$time_today."' 
     THEN `time_start` END DESC LIMIT 5 

如果在指定日期之後沒有5項小改變您的訂單TIME_START條件,你必須得到以前的記錄才能得到第5個計數。所以必須刪除日期檢查。

或者你可以試試這個子查詢還,

SELECT * 
FROM ( 
    SELECT *,(CASE WHEN `time_start` >= '".$time_today."' 
       THEN 0 ELSE 1 END) oflag 
    FROM `articles` 
    WHERE `type` = 'press' 
     AND `published` = '1' 
) T 
ORDER BY 
     oflag ASC, 
     CASE WHEN oflag = 0 THEN `time_start` END ASC, 
     CASE WHEN oflag = 1 THEN `time_start` END DESC LIMIT 5 
0

您的查詢應該是:

SELECT * FROM `articles` 
WHERE `type` = 'press' AND `published` = '1' 
AND `time_start` <= DATEADD(NOW(), INTERVAL 1 DAY) 
ORDER BY `time_start` DESC LIMIT 5 

你會得到五個結果在time_start場的降序排列。這是最好的解決方案,因爲您始終需要從數據庫中提取從NOW()開始24小時的5篇最新文章。即使type=press的數據庫中未找到與明天日期相同的記錄,那麼以降序排列的日期順序排列的5個較舊的記錄也將是查詢的結果,這也是您想要的結果。