Хорошо, у меня есть опыт работы с различными базами данных, но не Oracle, в частности, поэтому я все еще пытаюсь понять, как он справляется (например, отсутствие «Top» сводит меня с ума!) В любом случае, вот что мы » мы пытаемся сделать ...
Примечание. Мы используем Oracle 11. Я понимаю, что в Oracle 12 была добавлена новая функция (т.е. FETCH NEXT n ROWS ONLY
), но мы не можем используйте это, к сожалению.
Для начала у нас есть таблица статей (технически это представление, но я упрощаю его здесь). Вот соответствующие поля ...
- ID (целое число, первичный ключ)
- Заголовок (строка)
- Тело (строка)
- IsFavorite ('Y' или 'N')
- IsFeatured ('Y' или 'N')
- DatePublished (Date)
Можно отметить несколько статей как избранные и / или избранные.
То, что мы хотим вернуть, является результирующим набором, который имеет следующий порядок:
- Самая последняя опубликованная статья с
IsFeatured = 'Y'
, если таковые имеются. - Самая последняя опубликованная статья с
IsFavorite = 'Y'
, которая не является строкой из # 1 (это позволяет избежать дубликатов, если самая последняя добавленная статья также является самой последней избранной, и вместо этого выбирает следующая предпочтительная строка) если есть - Три последние опубликованные статьи, которые не являются № 1 или № 2, если таковые имеются
Вот что я придумала до сих пор (вырезано / вставлено / отредактировано здесь, так что могут быть некоторые опечатки), но это просто кажется мне неуклюжим ... как будто я трачу много ненужной обработки и итерации.
WITH mostRecentlyFeatured as (
Select * from (
Select 2 as MAJOR_SORT, A.*
From Articles A
where IsFeatured = 'Y'
order by DatePublished DESC
)
where ROWNUM = 1
),
mostRecentlyFavorited as (
Select * from (
Select 1 as MAJOR_SORT, A.*
From Articles A
minus Select * From mostRecentlyFeatured
where IsFavorite = 'Y'
order by DatePublished DESC
)
where ROWNUM = 1
),
topThreeOthers as (
Select * from (
select 0 as MAJOR_SORT, A.*
from Articles
minus
SELECT * from mostRecentlyFeatured
minus
SELECT * from mostRecentlyFavorited
order by DatePublished desc
)
where ROWNUM <= 3
),
finalRows as (
Select * from mostRecentlyFeatured
union all
Select * from mostRecentlyFavorited
union all
select * from topThreeOthers
)
Select * from finalRows
Order By MAJOR_SORT DESC,
DatePublished DESC;
Это не самый необычный из запросов, поэтому я не могу представить, что нет лучшего способа сделать это, но я просто еще не вижу его. Так есть ли?