1

我正在建立一个网站,用户可以在其中免费创建帖子。他们还可以为他们的帖子支付一些额外的知名度,这意味着付费帖子将首先显示在搜索结果中。付费帖子和未付费帖子都位于同一个表中,并且帖子是否付费是从列中计算出来的paid_until,该列仅包含一个时间戳。

现在,为了使分页变得容易,我希望能够从 MySQL 中获得一个不错的结果集,而无需通过 PHP 进行额外的排序,最好使用一个查询。结果集的总限制为 20(如每页 20 个帖子),它应该首先包含所有付费帖子(最多 20 个),然后添加 20-n 个未付费帖子。两个子集都应按其modified内部的列进行排序。我需要稍后通过设置一个OFFSET.

我尝试了、 和的不同变体JOIN,但没有想出一个能产生我想要的结果的解决方案。UNIONGROUP BY

有没有办法写这个:

(SELECT * FROM tbl_post WHERE paid_until >= :time_stamp ORDER BY modified DESC)
UNION
(SELECT * FROM tbl_post WHERE paid_until < :time_stamp ORDER BY modified DESC)

这样它就可以真正起作用,因为UNION弄乱了排序?

4

2 回答 2

1

就像是:

SELECT col1, col2, col3
FROM (    SELECT *,1 AS SortCol FROM tbl_post WHERE paid_until >= :time_stamp
          UNION
          SELECT *,2 AS SortCol FROM tbl_post WHERE paid_until < :time_stamp
      )AS sub
ORDER BY SortCol, modified DESC
于 2013-10-29T16:44:59.917 回答
1

您可以对 UNION 查询的结果进行排序:

(SELECT * FROM tbl_post WHERE paid_until >= :time_stamp)
UNION
(SELECT * FROM tbl_post WHERE paid_until < :time_stamp)
ORDER BY paid_until >= :time_stamp DESC, modified DESC

保留最后一个子查询周围的括号很重要,因此 ORDER BY 显然在子查询之外。否则 SQL 将 ORDER BY 单独应用于子查询,然后在执行 UNION 的过程中再次取消排序。

不需要对子查询进行排序,只需在最后一步进行即可。

但是这个查询可以进一步简化:

SELECT * FROM tbl_post
ORDER BY paid_until >= :time_stamp DESC, modified DESC
LIMIT :pagesize OFFSET :page_times_pagesize
于 2013-10-29T16:48:23.170 回答