2015-06-09 3 views
0

Предположим, у меня есть две таблицы Oracle SQL для моих счетов-фактур. INV_HEAD для адреса, даты, ... Затем у меня есть INV_POS для каждой позиции счета-фактуры.oracle sql сравнить результат два подзадачи

INV_HEAD 
-------- 
id 
date 
adr_id 
total 

INV_POS 
--------- 
id 
he_id 
pos 
art_id 
quantity 
price 

Я могу перечислить все счета-фактуры с

SELECT he.id, he.date, po.art_id, po.quantity, po.price 
FROM INV_HEAD he 
JOIN INV_POS po on po.he_id = he.id 

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

В результате мне нужен только INV_HEAD.id всех счетов-фактур с одинаковыми позициями.

Здесь же данные выборки:

id | he_id | pos | art_id | quantity | price 
1 |  1 | 1 | 1000 |  5 | 100.00 
2 |  1 | 2 | 2000 |  10 | 5000.00 
3 |  2 | 1 | 2500 |  2 | 1250.00 
4 |  3 | 1 | 2000 |  10 | 5000.00 
5 |  3 | 2 | 1000 |  5 | 100.00 

Счет с he_id 1 и 3 имеют одинаковые позиции.

+0

Ваш примерный запрос неверен для начала, потому что вы создаете перекрестное соединение между двумя таблицами. Вам нужно «ПРИСОЕДИНЯЙТЕ» их. –

+0

Вы могли бы добавить определения таблиц для двух таблиц, а также образец вывода того, что вы хотите видеть. – davegreen100

ответ

0

Вы хотите что-то вроде (обратите внимание, что следующий запрос не работает, потому что мы не можем сравнивать множества с помощью =):

SELECT SELECT DISTINCT H1.ID, H2.ID 
    FROM INV_HEAD H1, INV_HEAD H2 
    WHERE H1.ID <> H2.ID AND 
    (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) = 
    (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID) 

Но мы можем переосмыслить проблему: A = B также означает, что AB UNION BA - пустое множество.

Таким образом, вместо A = B вы можете использовать NOT EXISTS ((A MINUS B) UNION (B минус)) где А (SELECT ART_ID, количество, цена ОТ INV_POS ГДЕ HE_ID = H1.ID) и B является (SELECT ART_ID, количество, цена оТ INV_POS ГДЕ HE_ID = H2.ID)

Таким образом, ваш запрос:

SELECT DISTINCT H1.HE_ID, H2.HE_ID 
    FROM INV_HEAD H1, INV_HEAD H2 
    WHERE H1.ID <> H2.ID 
    AND NOT EXISTS(
    ((SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID) 
     MINUS 
    (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID)) 
     UNION 
    ((SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H2.ID) 
    MINUS 
    (SELECT ART_ID, QUANTITY, PRICE FROM INV_POS WHERE HE_ID = H1.ID))); 

Этот запрос создает пары счетов-фактур, которые имеют те же позиции (обратите внимание, что если два счета-фактуры не имеет должностей, которые считаются равными).

Условие H1.ID <> H2.ID избегает таких пар, как (1, 1) или (3, 3). Но если у вас есть пара (1,3), у вас также будет симметричная (3,1). Если вы хотите избежать симметрии, используйте вместо этого H1.ID < H2.ID или H1.ID> H2.ID.

Если вы хотите узнать счета-фактуры с таким же положением, как данный счет-фактура с ID = X, используйте WHERE H1.ID = X И H1.ID <> H2.ID AND .. (используйте <>, никогда не используйте < или> в данном случае).

+0

Держись, я должен переварить это первым ;-) – klammerauf

1

Вы можете использовать аналитическую функцию LISTAGG конкатенировать идентификатор с таким же положением

SELECT p.pos, LISTAGG(h.id, ', ') WITHIN GROUP (ORDER BY p.pos) "Id" 
FROM inv_head h, inv_pos p 
where h.id=p.he_id 
group by p.pos; 

Вы получите следующие результаты

POS Id

1 | 1, 2, 3

2 | 1, 3

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

+0

Большое спасибо, но столбец pos немного вводит в заблуждение здесь, поскольку он необходим только для сортировки, когда счет-фактура распечатаны. Я думаю, ваше решение будет работать и с p.he_id. – klammerauf

+0

Итак, я, по-видимому, пропустил, какова ваша мысль. Можете ли вы указать в своем вопросе образец желаемого результата? (конечно, p.he_id и h.id одинаковы) – Martina

+1

@klammerauf - Listagg() будет работать с he_id, как в этом [SQLFiddle] (http://sqlfiddle.com/#!4/7de31/1), где Первый запрос показывает все группы, соединенные одинаковыми позициями, второй запрос - группы, которые имеют такие же позиции, как данный идентификатор (например, это '1'). –

Смежные вопросы