Как записать строки в PL/SQL курсор в определенном порядке

Не понимаю, как записать в курсор строки в определенном (заданным некоторым условием) порядке. Т.е. интересующая строка должна попасть в результат select-а в любом случае, но требуется, чтобы она была именно последней в курсоре. Нужную сортировку подабрать не удалось, условие поставновки на последнее место определяется значением, которое лежит в одном из полей этой строки (в примере ниже условие s.service_synonym = 'AutoCloseOrder')
Пробовал через union, но он все равно не помещает нужную строку в конец курсора

create or replace procedure get_service2(p_document_id number, res out sys_refcursor)
is
begin
  open res for
  select s.service_id, s.service_synonym from document d
  join service s on d.service_id = s.service_id
  where d.document_id = p_document_id and (s.service_synonym <> 'AutoCloseOrder' or s.service_synonym is null) 
  union
  select s.service_id, s.service_synonym from document d
  join service s on d.service_id = s.service_id
  where d.document_id = p_document_id and s.service_synonym = 'AutoCloseOrder';
  --order by s.service_synonym desc;   
end get_service2;

Ответы (1 шт):

Автор решения: 0xdb

Это ошибка, считать, что запись последнего подзапроса в UNION будет выведена последней. UNION неявно сортирует предварительный результат по всем в нём присутствующим колонкам с целью устранения дубликатов.

Хорошо, но многие знают об этом и выключают неявное устранение дубликатов с UNION ALL. В этом случае, результат вроде выглядит, как ожидаемый (допустим нас интересует строка name=b):

create table t (id primary key, name) as 
    select rownum, trim (column_value) from xmlTable ('"a"," ", "b","c"')
/    

select t.* from t where name!='b' 
union all  
select t.* from t where name='b' 
/

        ID NAME
---------- ----
         1 a   
         4 c   
         3 b   

Но это ещё худшая ошибка, потому что порядок записей этого результата не гарантируется, ни стандартом SQL, ни документацией. Другими словами, сегодня порядок такой, завтра другой.

Порядок записей в результате запроса гарантируется только с ORDER BY, исключений нет:

select * 
from t 
order by case name when 'b' then 1 else 0 end, id
/

        ID NAME
---------- ----
         1 a   
         3 c   
         2 b   
→ Ссылка