Пользовательская логика ORDER BY в запросе SQL - PullRequest
0 голосов
/ 25 ноября 2011

Я ищу элегантное решение следующей проблемы:

У меня есть страница со списком записей ORDER BY date, с ограничением нумерации страниц. Вот фрагмент моего кода:

<?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. Выполнить два запроса - один для выбора записей с нужным внешним ключом, второй для выбора всех остальных. Объединить наборы результатов и .. обработать нумерацию страниц с помощью PHP.

В любом случае, мой элегантный подход SQL_CALC_FOUND_ROWS с одним запросом к нумерации страниц не будет работать. Мне было любопытно, есть ли какая-то «магия» MySQL, которую я мог бы использовать в предложении ORDER_BY?

Надеюсь, вышесказанное имеет смысл ..

Ответы [ 2 ]

3 голосов
/ 25 ноября 2011

Используйте простой 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 голос
/ 25 ноября 2011

Это не очень элегантно, но вы можете использовать UNION, чтобы объединить результат двух вложенных выборок, что означает, что MySQL все равно будет обрабатывать нумерацию страниц.Однако это не будет очень производительным, поскольку MySQL все равно придется извлекать все результаты целиком.

...