SQL查询中的自定义ORDER BY逻辑

时间:2011-11-25 11:49:05

标签: php mysql pagination sql-order-by sql-calc-found-rows

我正在寻找以下问题的优雅解决方案:

我目前有一个列出ORDER BY日期条目的页面,并带有分页限制。这是我的代码片段:

<?php
$intPageNumber = 1;
if ( isset($this->GET['p']) && (integer)$this->GET['p'] > 1 ) $intPageNumber = (integer)$this->GET['p'];
$strLimit = " LIMIT " . (($intPageNumber-1)*$intItemsPerPage) . ", " . $intItemsPerPage;

$sql = "SELECT SQL_CALC_FOUND_ROWS * FROM jos_h_testimonials ORDER BY date DESC ".$strLimit;
// code to load some records here
// ...

// take care of pagination
$db->setQuery('SELECT FOUND_ROWS()');
$intTotalRecords = $db->LoadResult();
$this->NumberOfPages = ceil( $intTotalRecords / $intItemsPerPage);
$this->CurrentPage = $intPageNumber;
?>

表架构:

CREATE TABLE IF NOT EXISTS `jos_h_testimonials` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `author` varchar(255) NOT NULL,
  `testimonial` text NOT NULL,
  `rating` int(11) NOT NULL,
  `date` int(11) NOT NULL,
  `hgroup_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

这是以分页方式处理列表条目的非常标准的方式。 我的问题是客户想要特殊订购 - 他们希望条目具有特定值,hgroup_id外键出现在顶部。

我能想到的两个解决方案是:

  1. 加载整个列表并使用PHP重新排序,然后使用PHP处理分页;
  2. 运行两个查询 - 一个用于选择具有所需外键的条目,第二个用于选择所有其他entires。使用PHP合并结果集和..处理分页。
  3. 无论哪种方式,我优雅的单一查询SQL_CALC_FOUND_ROWS分页方法都行不通。我很好奇是否可以在ORDER_BY子句中使用一些MySQL“魔法”?

    我希望以上内容有道理..

2 个答案:

答案 0 :(得分:3)

使用简单的SQL:

SELECT SQL_CALC_FOUND_ROWS *
FROM jos_h_testimonials
ORDER BY
    -- Special case on top
    CASE WHEN hgroup_id = 9 THEN 0
    -- All the rest
    ELSE 1 END ASC,
    -- Regular sort order
    date DESC

答案 1 :(得分:1)

它不是非常优雅,但您可以使用UNION来组合两个子选择的结果,这意味着MySQL仍然会处理分页。但是,它不会非常高效,因为MySQL仍然需要获取每个结果的全部内容。