Oracle находит общее местоположение между различными ограничительными «кодами» - PullRequest
1 голос
/ 11 октября 2019

это мой первый вопрос здесь. Мне нужно в основном найти общее местоположение между различными кодами ограничений для номера ингредиента. Коды ограничений и местоположения находятся в их собственной таблице. Мой текущий запрос возвращает что-то вроде этого (есть еще данные для этого вопроса, но он не нужен для этого вопроса)

ingredient_number   restriction_code
-----------------   -------------------
 001                NN
 001                R-03
 001                R-02
 002                R-22
 002                NN
 003                R-03

Таблица со всеми ограничениями и их расположением выглядит следующим образом

restriction_code   location
----------------   --------
NN                 CLE
NN                 LAX
NN                 ORD
NN                 JFK
NN                 PIT
NN                 DFW
R-03               CLE
R-03               LAX
R-02               LAX
R-02               DFW
R-22               JFK
R-03               PIT

Мне нужно, чтобы результаты выглядели так:

ingredient_number  restriction_code common_loc
-----------------  ---------------- ----------
001                NN               LAX
001                R-03             LAX
001                R-02             LAX
002                R-22             JFK
002                NN               JFK
003                R-03             PIT

LAX является общим для всех трех кодов ограничения, поэтому мы выбираем этот в этом примере.

Я предполагаю, что мне нужно будет использовать внутреннее соединение, чтобы соединить общие места, но я не знаю, как это выяснить. Любая помощь будет принята с благодарностью! Мне просто нужно указать в правильном направлении.

Ответы [ 2 ]

0 голосов
/ 11 октября 2019

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

Немного глупо повторять все коды ограничений для ингредиента в вывод запроса;Я показываю по одной строке для каждого (номер_ ингредиента, местоположение), которое удовлетворяет вашему условию.

Настройка:

create table restriction_codes (ingredient_number, restriction_code) as
    select '001', 'NN'   from dual union all
    select '001', 'R-03' from dual union all
    select '001', 'R-02' from dual union all
    select '002', 'R-22' from dual union all
    select '002', 'NN'   from dual union all
    select '003', 'R-03' from dual union all
    select '004', 'CCC'  from dual union all
    select '004', 'DDD'  from dual
;

create table locations (restriction_code, location) as
    select 'NN'  , 'CLE' from dual union all
    select 'NN'  , 'LAX' from dual union all
    select 'NN'  , 'ORD' from dual union all
    select 'NN'  , 'JFK' from dual union all
    select 'NN'  , 'PIT' from dual union all
    select 'NN'  , 'DFW' from dual union all
    select 'R-03', 'CLE' from dual union all
    select 'R-03', 'LAX' from dual union all
    select 'R-02', 'LAX' from dual union all
    select 'R-02', 'DFW' from dual union all
    select 'R-22', 'JFK' from dual union all
    select 'R-03', 'PIT' from dual union all
    select 'CCC' , 'ORD' from dual union all
    select 'DDD' , 'LGA' from dual
;

Запрос и вывод:

with
  prep (ingredient_number, restriction_code, restriction_count) as (
    select ingredient_number, restriction_code, 
           count(*) over (partition by ingredient_number)
    from   restriction_codes
  )
select p.ingredient_number, l.location
from   prep p inner join locations l on p.restriction_code = l.restriction_code
group  by p.ingredient_number, p.restriction_count, l.location
having count(*) = p.restriction_count
order  by p.ingredient_number, l.location
;

INGREDIENT_NUMBER  LOCATION
------------------ --------
001                LAX     
002                JFK     
003                CLE     
003                LAX     
003                PIT 

РЕДАКТИРОВАТЬ - ОП пояснил, что ему действительно необходимо показать все входные строки в выходных данных (по одной строке для каждого кода ограничения для пар (ингредиент, местоположение), которые удовлетворяют требованию).

Здеськак это можно сделать:

select ingredient_number, restriction_code, location
from   (
         select r.ingredient_number, r.restriction_code, l.location,
                count(distinct r.restriction_code) 
                    over (partition by r.ingredient_number) as global_ct,
                count(r.restriction_code) 
                    over (partition by r.ingredient_number, l.location) as local_ct
         from   restriction_codes r inner join locations l 
                                    on r.restriction_code = l.restriction_code
       )
where  global_ct = local_ct
order  by ingredient_number, location, restriction_code
;

INGREDIENT_NUMBER  RESTRICTION_CODE   LOCATION
------------------ ------------------ --------
001                NN                 LAX     
001                R-02               LAX     
001                R-03               LAX     
002                NN                 JFK     
002                R-22               JFK     
003                R-03               CLE     
003                R-03               LAX     
003                R-03               PIT  
0 голосов
/ 11 октября 2019

Используя общее табличное выражение, объедините две таблицы. Затем присоедините CTE к себе в зависимости от местоположения. Теперь, если используется более 1 местоположения, вы получите несколько магазинов на ингредиент.

WITH CTE AS (T1.Ingredient_Number, T1.Restriction_Code, T2.Location
SELECT *
FROM T1
INNER JOIN T2
 on T1.Restriction_Code = T2.Restriction_Code)

SELECT A.Ingredient_Number, A.Restriction_Code
FROM CTE A
INNE JOIN CTE B
  on A.Ingredient_Number = B.Ingredient_Number
 and A.Location = B.Location
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...