Объединить данные в Oracle без дублирования строки GRN - PullRequest
0 голосов
/ 26 февраля 2019

Например: Правило: 1 счет-фактура имеет n D / O, 1 D / O имеет n GRN Таблица-фактура + D / O: (A)

Invoice_no  |Line |DO_NUM    |DO_LINE |CUS_PO   |PO_LINE |ITEM      |INV_QTY
8100OPN02173|0001 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100
8100OPN02173|0002 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100
8100OPN02173|0003 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|300

.... Таблица GRN + D /O: (B)

DO_NUM    |DO_LINE|GRN_NUM |GRN_LINE|BASE_COST_AMT|COST_AMT|QTY
2000004479|0001   |70001802|0007    |19560690     |837     |100
2000004479|0001   |70001896|0001    |19577430     |837     |100
2000004479|0001   |70002020|0001    |11082286     |476.76  |300

....

Сейчас я использую запрос:

Select Distinct * 
from A 
left join B 
where 
a.do_num = b. do_num
and a.do_line = b.do_line
and a.inv_qty = b.qty

, но результат показывает не то, что я хочу (о технических - это правильно) потому что строка счета 1 не имеет GRN 70001896, а строка 2 не имеет GRN 70001802. Строка 4,5 не существует в реальности.Как это можно исправить?

Invoice_no  |Line |DO_NUM    |DO_LINE |CUS_PO   |PO_LINE |ITEM      |INV_QTY |GRN_NUM |GRN_LINE|BASE_COST_AMT|COST_AMT|QTY
8100OPN02173|0001 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100     |70001802|0007    |19560690     |837     |100
8100OPN02173|0002 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100     |70001896|0001    |19577430     |837     |100
8100OPN02173|0003 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|300     |70002020|0001    |11082286     |476.76  |300
8100OPN02173|0001 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100     |70001896|0001    |19577430     |837     |100
8100OPN02173|0002 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100     |70001802|0007    |19560690     |837     |100

Мне нужны такие данные:

Invoice_no  |Line |DO_NUM    |DO_LINE |CUS_PO   |PO_LINE |ITEM      |INV_QTY |GRN_NUM |GRN_LINE|BASE_COST_AMT|COST_AMT|QTY
8100OPN02173|0001 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100     |70001802|0007    |19560690     |837     |100
8100OPN02173|0002 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|100     |70001896|0001    |19577430     |837     |100
8100OPN02173|0003 |2000004479|0001    |20190123 |0001    |HT02Y  NAT|300     |70002020|0001    |11082286     |476.76  |300

...

1 Ответ

0 голосов
/ 26 февраля 2019

В вашей модели данных нет ничего, что могло бы связать определенную строку в 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

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

Было бы намного проще, если бы ассоциация была включена в вашу модель данных, конечно ...

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