我正在建立一个网站,用户可以免费创建帖子。他们还可以为他们的帖子支付额外的可见度,这意味着付费帖子将首先显示在搜索结果中。付费和非付费帖子都位于同一个表格中,而且是否付款的帖子是从paid_until
列计算的,该列只包含一个时间戳。
现在,为了简化分页,我希望能够从MySQL获得一个不错的结果集,而不需要PHP进行额外的排序,最好是一个查询。结果集的总限制为20(如每页20个帖子),它应首先包含所有付费帖子(最多20个),然后添加20-n个未付帖子。两个子集都应按其自身的modified
列进行排序。我需要稍后通过设置OFFSET
跳过相同的结果。
我尝试了JOIN
,UNION
和GROUP 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
会弄乱排序?
答案 0 :(得分: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
答案 1 :(得分: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