powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Практика получения данных по нескольким условиям с разными приоритетами
11 сообщений из 11, страница 1 из 1
Практика получения данных по нескольким условиям с разными приоритетами
    #39899135
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите, есть ли какие-то устоявшиеся способы или рекомендации, если нужно получить из БД данные (строку) в соответствии с одним из нескольких условий, у которых имеются разные приоритеты.
Допустим нужно получить значение столбца client_id из набора данных в соответствии со следующими требованиями:
1. Если есть строка с is_vip=1, то из этой строки.
2. Если в п.1 ничего нет, то для строк с заданным prio выбрать строку с минимальными prio, prio_date.
3. Если в п.2 тоже ничего нет, то из строки с минимальным order_id.

Я для себя не определился, как это делать оптимально.
Иногда использую cross-join для каждого условия и coalesce.
Чаще использую выборки для каждого варианта, объединенные через union all, в которым добавляется числовое значение (соответствующее приоритету варианта), с последующей сортировкой и выбором rownum=1.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899162
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем пихать 10 pounds of shit in a 5-pound bag? Выполняй поэтапно.

SY.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899166
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поэтапно конечно проще.
Но это означает, что вместо одного запроса сервер будет выполнять три, с передачей данных от клиента и обратно на каждом запросе.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899167
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
Поэтапно конечно проще.
Но это означает, что вместо одного запроса сервер будет выполнять три, с передачей данных от клиента и обратно на каждом запросе.

сделай функцию/процедуру на сервере
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899173
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Даже на сервере это будет три переключения контекста, вместо одного.
Но суть я понял, так лучше не делать.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899176
iOracleDev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
переключения контекста
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899177
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.это означает, что вместо одного запроса сервер будет выполнять три

"И чо?" (с)

Тебя беспокоит консистентность трёх резалт сетов или hard parse трёх простых запросов
вместо одного сложного?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899178
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.

Но это означает, что вместо одного запроса сервер будет выполнять три, с передачей данных от клиента и обратно на каждом запросе.


Уточним. Не три а от одного до трех - как карта ляжет. И передача данных будет только от последнего. Предыдущие вернут no_data_found.

sy.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899179
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можешь предоставить тестовые данные?

Навскидку такой вариант:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select client_id from table t 
where case when is_vip = 1 
           then 1 
           else case when prio = (select min(prio) from table t2 where t.client_id = t2.client_id)
                     then 2
                     else case when order_id = (select min(order_id) from table t3 where t.client_id = t3.client_id)
                               then 3
                               else 0 end end end >= 1



Но не факт, что он будет лучше чем 3 юниона.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899205
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть список тарифов, наименования которых формируются по определенному шаблону:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
with T as
(
  select 0 as ID, '' as SCOPE, '' as CATEGORY, '' as CODE, 0 as PRIO from DUAL where 0=1
  union all select 1, 's1', 'Базовый Холодный', 'БХ', null from DUAL
  union all select 2, 's1', 'Базовый Теплый', 'БТ', null from DUAL
  union all select 3, 's1', 'Базовый Плюс Холодный', 'БПХ', null from DUAL
  union all select 4, 's1', 'Базовый Плюс Теплый', 'БПТ', null from DUAL
  union all select 5, 's1', 'Расширенный Холодный', 'РХ', 1 from DUAL
)



Эти тарифы распределены по линейкам тарифов, в пределах которой у них есть какие-то общие признаки:
Код: plsql
1.
2.
3.
4.
5.
6.
with TL as
(
  select '' as LINE from DUAL where 0=1
  union all select 'Базовый' from DUAL
  union all select 'Базовый Плюс' from DUAL
)



Название линейки тарифов совпадает с началом названия тарифов. Но простой джойн с помощью like неприменим, потому что возможны перекрытия (например начало "Базовый" есть как в "Базовый *", так и в "Базовый Плюс *"). Поэтому приходится использовать вначале сортировать по длине совпадения, а затем группировать.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
with T as
(
  select 0 as ID, '' as SCOPE, '' as CATEGORY, '' as CODE, 0 as PRIO from DUAL where 0=1
  union all select 1, 's1', 'Базовый Холодный', 'БХ', null from DUAL
  union all select 2, 's1', 'Базовый Теплый', 'БТ', null from DUAL
  union all select 3, 's1', 'Базовый Плюс Холодный', 'БПХ', null from DUAL
  union all select 4, 's1', 'Базовый Плюс Теплый', 'БПТ', null from DUAL
  union all select 5, 's1', 'Расширенный Холодный', 'РХ', 1 from DUAL
)
, TL as
(
  select '' as LINE from DUAL where 0=1
  union all select 'Базовый' from DUAL
  union all select 'Базовый Плюс' from DUAL
)
, RS as
(
  select T.ID, T.SCOPE
  , max(TL.LINE) keep (dense_rank last order by length(TL.LINE)) as LINE
  from T
  left join TL on (upper(TL.LINE) = upper(substr(T.CATEGORY, 1, length(TL.LINE))))
  group by T.ID, T.SCOPE
)
select *
from RS
join T on (T.ID = RS.ID)



Мне нужно из этого списка выбрать один тариф.
Если есть — то из линейки "Базовый Плюс", с минимальным приоритетом и номером.
Если такового нет, то любой другой, с минимальным приоритетом и номером.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select * from (
  (
    select 0 as POS, ID, LINE, PRIO
    from RS join T using (ID)
    where upper(LINE) = upper('Базовый Плюс')
    union all
    select 1 as POS, ID, LINE, PRIO
    from RS join T using (ID)
  )
  order by POS, PRIO nulls last, ID
) where rownum = 1



Если делать это поэтапно, то раздувается рутинный код.
...
Рейтинг: 0 / 0
Практика получения данных по нескольким условиям с разными приоритетами
    #39899222
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.раздувается рутинный код.

Нарушение первой НФ всегда карается геморроем. Страдайте.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Практика получения данных по нескольким условиям с разными приоритетами
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]