Это один из способов найти все места, где можно найти все коды ограничений для данного ингредиента. Если для ингредиента нет единого местоположения, в котором можно найти все ограничения, этот ингредиент будет исключен из выходных данных. Если для ингредиента есть несколько мест, где можно найти все коды ограничений для этого ингредиента, то ВСЕ эти места отображаются в выходных данных.
Немного глупо повторять все коды ограничений для ингредиента в вывод запроса;Я показываю по одной строке для каждого (номер_ ингредиента, местоположение), которое удовлетворяет вашему условию.
Настройка:
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