Это лучше всего решается в MySQL как исключающее соединение .Это очень похоже на многие вопросы, на которые дан ответ с помощью тега «наибольший n для группы» в StackOverflow.
SELECT p.name, p.url_name
FROM pages p
LEFT OUTER JOIN pages p2 ON p.order_number > p2.order_number
AND (p2.parent_id, p2.active, p2.visible, p2.deleted) = ({$main_page["id"], 1, 1, 0)
WHERE (p.parent_id, p.active, p.visible, p.deleted) = ({$main_page["id"]}, 1, 1, 0)
AND p2.id IS NULL;
Это решение ищет строку p2
, которая имеет более низкий порядковый номер и в других случаях соответствует тем же условиямкак p
.Если такая строка с более низким порядком не найдена, то p
должен иметь самый низкий order_id из тех в той же группе, которая соответствует условию, то есть с тем же идентификатором parent_id.
Если у вас составной индекс на(parent_id, active, visible, удален, order_id), это должен быть очень эффективный запрос.
Одна часть этого решения, которую вы можете не ожидать, это то, что вам нужно повторить условия внутри левых критериев соединения.
Я отредактировал запрос выше после его тестирования.Теперь должно работать лучше.Обратите внимание, что это не сравнивает order_number подстраницы с порядковым номером ее родителя - он сравнивает order_number подстраницы с именем его родного элемента, то есть подстраниц того же родителя.