2016-03-28 65 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个较旧的记录也将是查询的结果,这也是您想要的结果。