В вашей модели данных нет ничего, что могло бы связать определенную строку в B с определенной строкой в A, когда выполнены все условия соединения.Первые две строки в A соответствуют обеим из первых двух строк в B, потому что все они имеют одинаковые do_num
, do_line
и количество.Нечего сказать, что строка счета 0001 связана с grn_num
70001802, но не с 70001896. (Также не уверен, почему вы, кажется, храните числа как строки с нулевым заполнением, но, надеюсь, у вас есть причина для этого.)
На основании ограниченных данных вы можете получить желаемый результат, сделав некоторые предположения - в частности, здесь вы хотите, чтобы значения по возрастанию grn_num
были связаны с номерами строк накладных по возрастанию, и всегда будет одинаковое число Aи B строк для указанных вами условий соединения (левое соединение означает, что оно все равно будет возвращать данные, если B меньше, чем As, но некоторые будут неполными строками; и если B больше, чем As, то некоторые данные B будут отсутствовать).
Исходя из этих или ваших собственных предположений, вы можете добавить псевдостолбец к данным в каждой таблице, используя аналитическую функцию, например row_number()
, в основном с предположениями в предложении partition by
, что-то вроде:
select a.*,
row_number() over (partition by do_num, do_line, inv_qty order by "Line") as rn
from a
и
select b.*,
row_number() over (partition by do_num, do_line, qty order by grn_num) as rn
from b
, а затем объединить результаты этих подзапросов (встроенные представления):
select a."Invoice_no", a."Line", a.do_num, a.do_line, a.cus_po, a.po_line, a.item, a.inv_qty,
b.grn_num, b.grn_line, b.base_cost_amt, b.cost_amt, b.qty
from (
select a.*,
row_number() over (partition by do_num, do_line, inv_qty order by "Line") as rn
from a
) a
left join (
select b.*,
row_number() over (partition by do_num, do_line, qty order by grn_num) as rn
from b
) b
on b.do_num = a.do_num
and b.do_line = a.do_line
and b.qty = a.inv_qty
and b.rn = a.rn
С вашими образцами данных в CTE:
-- CTEs for sample data
with a ("Invoice_no", "Line", do_num, do_line, cus_po, po_line, item, inv_qty) as (
select 8100OPN02173, '0001', 2000004479, '0001', 20190123, '0001', 'HT02Y NAT', 100 from dual
union all
select 8100OPN02173, '0002', 2000004479, '0001', 20190123, '0001', 'HT02Y NAT', 100 from dual
union all
select 8100OPN02173, '0003', 2000004479, '0001', 20190123, '0001', 'HT02Y NAT', 300 from dual
), b (do_num, do_line, grn_num, grn_line, base_cost_amt, cost_amt, qty) as (
select 2000004479, '0001', 70001802, '0007', 19560690, 837, 100 from dual
union all
select 2000004479, '0001', 70001896, '0001', 19577430, 837, 100 from dual
union all
select 2000004479, '0001', 70002020, '0001', 11082286, 476.76, 300 from dual
)
-- actual query
select a."Invoice_no", a."Line", a.do_num, a.do_line, a.cus_po, a.po_line, a.item, a.inv_qty,
b.grn_num, b.grn_line, b.base_cost_amt, b.cost_amt, b.qty
from (
select a.*,
row_number() over (partition by do_num, do_line, inv_qty order by "Line") as rn
from a
) a
left join (
select b.*,
row_number() over (partition by do_num, do_line, qty order by grn_num) as rn
from b
) b
on b.do_num = a.do_num
and b.do_line = a.do_line
and b.qty = a.inv_qty
and b.rn = a.rn
/
Invoice_no Line DO_NUM DO_L CUS_PO PO_L ITEM INV_QTY GRN_NUM GRN_ BASE_COST_AMT COST_AMT QTY
---------- ---- ---------- ---- ---------- ---- ---------- ---------- ---------- ---- ------------- ---------- ----------
8100 0001 2000004479 0001 20190123 0001 HT02Y NAT 100 70001802 0007 19560690 837 100
8100 0002 2000004479 0001 20190123 0001 HT02Y NAT 100 70001896 0001 19577430 837 100
8100 0003 2000004479 0001 20190123 0001 HT02Y NAT 300 70002020 0001 11082286 476.76 300
Будет ли этот подход и эти предположения работать для всех ваших других данных, что вы будете иметьдля проверки.
Было бы намного проще, если бы ассоциация была включена в вашу модель данных, конечно ...