#sql #oracle #left-join
Вопрос:
У меня есть левое внешнее соединение, которое возвращает не все строки из «левой» таблицы. У меня нет предложения where, поэтому после соединения не следует применять фильтрацию.
Я ожидаю:
Продукт 1 | около | 100 |
Продукт 2 | около | 25 |
Продукт 4 | около | 57 |
Продукт 1 | gr | 45 |
Продукт 2 | gr | 22 |
Продукт 3 | gr | 5 |
Продукт 4 | gr | 4 |
Продукт 3 | нулевой | нулевой |
Но я пропускаю последний ряд. Любой свет, который вы могли бы пролить на это, очень ценится.
Чтобы воспроизвести его:
-- Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
drop table t1;
drop table t2;
create table t1
(ov_product varchar2(18 byte)
,product varchar2(18 byte)
)
/
create table t2
(reporting_month number
,product varchar2(18 byte)
,sender varchar2(2 byte)
,items number
)
/
insert into t1
(
select 'Product 1' ov_product, 'P1' product from dual
union
select 'Product 2' ov_product, 'P2' product from dual
union
select 'Product 3' ov_product, 'P3' product from dual
union
select 'Product 4' ov_product, 'P4' product from dual
);
insert into t2
(
select 202108, 'P1', 'AT', 100 from dual
union
select 202108, 'P2', 'AT', 25 from dual
union
-- no P3 for AT
select 202108, 'P4', 'AT', 57 from dual
union
select 202108, 'P1', 'GR', 45 from dual
union
select 202108, 'P2', 'GR', 22 from dual
union
select 202108, 'P3', 'GR', 5 from dual
union
select 202108, 'P4', 'GR', 4 from dual
)
;
commit;
select t1.ov_product
,t2.sender
,t2.items
from t1
left outer join t2
on t1.product = t2.product
order by 2, 1
;
Ответ №1:
Ваше внешнее соединение работает нормально.
Вы, вероятно, имеете в виду секционированное внешнее соединение.
Смотрите дополнительные query_partition_clause
в соединении
PARTITION BY (sender)
только это соединение заполнит пробелы, sender
как вы и ожидали.
select t1.ov_product
,t2.sender
,t2.items
from t1
left outer join t2
PARTITION BY (sender)
on t1.product = t2.product
order by 2, 1
OV_PRODUCT SE ITEMS
------------------ -- ----------
Product 1 AT 100
Product 2 AT 25
Product 3 AT
Product 4 AT 57
Product 1 GR 45
Product 2 GR 22
Product 3 GR 5
Product 4 GR 4
Ответ №2:
Так как в t2 есть строка с продуктом 3, нет записи с нулевым значением, которую нужно создать с помощью соединения слева.
Чтобы получить такую строку, вам нужно либо присоединиться к таблице отправителей, если она у вас есть. Или, если таблица не существует, вы можете использовать CTE, как это
с отправителями(отправителем) как (выберите отдельный отправитель из t2)
with senders(sender) as (select distinct sender from t2)
select t1.ov_product
,t2.sender
,t2.items
from t1
cross join senders
left outer join t2
on t1.product = t2.product
and t2.sender = senders.sender
order by 2, 1;