目前我在Typecho圈里看见的文章置顶实现都是使用两个 Select,第一个Select是查询置顶的文章,第二个Select是查询剩余的文章。
这样实现有BUG,而且也不优雅。
置顶x篇文章首页文章数就变成 pageSize + x 了。
PS:本站的 XMLiving 主题支持完美置顶哦
法1
最简单就是新增一个排序字段了。这是MySQL的,SQLITE怎么写忘记了。
ALTER TABLE `prefix_contents` ADD `sticky` DEFAULT 0;
这样的缺点就是多一个没什么用字段,毕竟只有很少的文章需要置顶。而且修改sticky字段麻烦还需要写一个接口来实现。
查询的时候双字段排序就行。
select * from `prefix_contents` order by sticky desc, created desc
法2
把置顶字段信息存到 prefix_fields
表。
使用any_value()
来防止值不存在。
同样的双字段排序。
select *, any_value(`int_value`) as sticky from `prefix_contents` left outer join `prefix_fields` on `prefix_contents`.`cid` = `prefix_fields`.`cid` group by `prefix_contents`.`cid` order by sticky desc, created desc
法3(推荐)
把使用 case 来生成置顶字段
88,90就是想置顶的文章
select *, case when cid in (88, 90) then 100 else 0 end sticky from xmp_contents xc order by sticky desc,created desc;
结果还是要增加字段吗。。其实你说的那个BUG也是有解决方法的,$this->parameter->pageSize就是。
法3不用加字段啊
直接设置$this->parameter->pageSize会丢文章,有多少置顶丢多少
这个方法确实优雅了,不过我想了下,这样应该会降低查询效率,程序得一个个去匹配所有文章,计算出“case when cid in (88, 90) then 100 else 0 end”的值,然后进行排序,用不上索引了。法1的话得给新字段加索引。法2排序用了两个表的字段,也得全表扫描。。
其实本来就有 order 字段了,所以法1利用原来的 order 字段就行