Oracle SQL создать виртуальный столбец, сделать максимум, а затем подсчитать и отобразить записи - PullRequest
1 голос
/ 24 марта 2020

Извините, если название немного вводит в заблуждение, но я не знаю, как еще его выразить. В любом случае вернемся к проблеме под рукой. У меня есть 2 таблицы WSM (содержит идентификатор хранилища, имя и связанный с ним риск) и SUTSM_REP (отношение хранилища и склада). Ниже приведены значения, которые они содержат: таблица WSM

SUTSM_REP

Каждый склад имеет связанный с ним риск (4 категории риска - низкий, средний , High & Critical) и магазин получает вещи с нескольких складов. Если магазин получает товары с 3 складов (например, w1 (средний риск), w2 (высокий), w3 (низкий)), тогда риск, связанный с магазином, «Высокий». Точно так же, если магазин получает товары с 2 складов - 1 со средним и другой с низким риском, тогда магазин получает «средний» риск. Я надеюсь, что я ясно с этим пунктом. Меня попросили подсчитать количество магазинов с каждым риском. Поэтому я создал еще одну таблицу с идентификатором риска и риска. Я назначил 1 для низкого, 2 для среднего, 3 для высокого и 4 для критического. Затем я присоединился к 3 таблицам вместе с максимальным идентификатором риска, а затем сделал подсчет этого. Ниже мой запрос:

select RID, count(sp_id)
from
  (select a.sp_id, max(c.r_id) AS RID
   from SUTSM_REP a,
        WSM b,
        wsm_rid c
   where a.sm_id = b.sm_id and b.smr = c.smr
   group by a.sp_id) t
group by RID;

И результат: Результат моего запроса

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

with t as (
  select sm_id, sm_name, smr, DECODE(smr, 'Low', 1,
                                    'Medium', 2,
                                    'High', 3,
                                    'Critical', 4,
                                    0) RISK_ID 
   from wsm )
select rid, count(sp_id) from 
    ( select sp_id, max(risk_id) rid 
      from (select a.sp_id, b.sm_id, b.risk_id 
            from SUTSM_REP a, t b 
            where a.sm_id=b.sm_id) 
       group by sp_id ) 
group by rid;

Я создал временную таблицу с помощью wsm и добавил идентификатор риска в категорию / уровень риска. А потом использовал тот же лог c, что и раньше. Вывод этого запроса :

Мы используем Oracle SQL. Может кто-нибудь помочь мне или указать мне, как получить названия категорий / уровней риска? Я в своем уме остроумие здесь. Заранее благодарен всем постерам за помощь.

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

Лучше всего иметь таблицу рисков, содержащую названия рисков и их актуальность. Если вам не разрешено создавать такие таблицы, создайте их как ad-ho c представление с WITH на лету.

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

Последний шаг - подсчет магазинов по риску.

with risks as
(
  select 'Low' as smr, 1 as relevance from dual
  union all
  select 'Medium' as smr, 2 as relevance from dual
  union all
  select 'High' as smr, 3 as relevance from dual
  union all
  select 'Critical' as smr, 4 as relevance from dual
)
, store_risks as
(
  select
    sw.sp_id,
    max(w.smr) keep (dense_rank last order by r.relevance) as risk,
    max(r.relevance) as risk_sortkey
  from sutsm_rep sw -- the store/warehouse bridge
  join wsm w on w.sm_id = sw.sm_id -- the warehouses
  join risks r on r.smr = w.smr -- the risks
  group by sw.sp_id
)
select risk, count(*)
from store_risks
group by risk
order by max(risk_sortkey);
0 голосов
/ 24 марта 2020

Поможет ли decode RISK_ID вернуться в соответствующие категории? Пример ниже ..

with t as (
  select sm_id, sm_name, smr, DECODE(smr, 'Low', 1,
                                    'Medium', 2,
                                    'High', 3,
                                    'Critical', 4,
                                    0) RISK_ID 
   from wsm )
select rid, 
DECODE(rid, 1, 'Low',
            2, 'Medium',
            3, 'High',
            4, 'Critical') smr,
count(sp_id) from 
    ( select sp_id, max(risk_id) rid 
      from (select a.sp_id, b.sm_id, b.risk_id 
            from SUTSM_REP a, t b 
            where a.sm_id=b.sm_id) 
       group by sp_id ) 
group by rid;



В качестве альтернативы, вы можете использовать функцию rank

select smr, count(distinct sp_id) from (
select s.sp_id, w.smr,
rank () over (partition by s.sp_id order by 
DECODE(smr, 'Low', 1,
            'Medium', 2,
            'High', 3,
            'Critical', 4,
             0) desc
) rnk
from wsm w
join sutsm_rep s on w.sm_id = s.sm_id
) where rnk = 1
group by smr
;



Если это не работает Пожалуйста, поделитесь ожидаемым результатом. Также, пожалуйста, рассмотрите возможность использования db fiddle. Я добавил образец здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...