Я буду использовать гипотетический пример, чтобы проиллюстрировать мою проблему объединения двух таблиц, на которых я застрял довольно давно:
Каждый Заказ имеет много дат и количеств поставки:
Заказать
OrderID DeliveryID DeliveryDate Quantity
======= ========== ============ ========
1000 001 2017-01-01 10
1000 002 2017-01-08 10
1000 003 2017-01-15 10
1001 001 .... 10
Полученные товары 1013 * отображаются на OrderID, но не DeliveryID:
Полученное
OrderID InvoiceID ReceivedDate ReceivedQuantity
======= ========= ============ ================
1000 1001 2017-01-01 10
1000 1002 2017-01-09 09
1000 1003 2017-01-10 01
1000 1004 2017-01_15 10
Я сейчас пытаюсь присоединить таблицу Received к моей таблице Order. Но поскольку, например, второй заказ получен в два отдельных этапа, я хочу присоединить заказ к последней полученной строке, поскольку только тогда мой заказ полностью поступил.
При обычном присоединении через OrderID мы получили бы, в верхнем примере 3 Заказа и 4 Получения, всего 12 соединенных элементов.
Итак, я хочу решить эту проблему, накапливая количество для каждого идентификатора заказа и каждой поставки относительно идентификатора заказа, при этом мои скорректированные таблицы выглядят так:
Заказать
OrderID DeliveryID DeliveryDate Quantity OrderedAccumQuant
======= ========== ============ ======== ================
1000 001 2017-01-01 10 10
1000 002 2017-01-08 10 20
1000 003 2017-01-15 10 30
1001 001 .... 10 10
Полученное
OrderID InvoiceID ReceivedDate ReceivedQuantity AccumQuant
======= ========= ============ ================ ================
1000 1001 2017-01-01 10 10
1000 1002 2017-01-09 09 19
1000 1003 2017-01-10 01 20
1000 1004 2017-01_15 10 30
Моя запланированная логика теперь состоит в том, чтобы соединить таблицу Received с таблицей Order с первой строкой Received, которая имеет равное или большее значение ReceivedAccumQuant, чем OrderedAccumQuant. В этом примере InvoiceID 1002 не объединяется, поскольку его доставленное количество не является заказанным количеством.
Желаемый выход:
Ordered Rec
OrderID DelivID DeliveryDate Quant AccQuant RecDate InvoiceID AccQu
======= ======= ============ ===== ======= ======= ========= =====
1000 001 2017-01-01 10 10 .-01-01 1001 10
1000 002 2017-01-08 10 20 .-01-10 1003 20
1000 003 2017-01-15 10 30 .-01-15 1004 30
1001 001 ....
Требуемый вывод будет отображать меня в каждом OrderID: совпадение всех DeliveryID с InvoiceID, где receive_accumulated_quantity> =, чем order_accumulated_quantity
Мои два подхода:
Проблема выделения памяти
Один из подходов заключался во внутреннем присоединении к таблице «Получено» через подзапрос, а затем в ранжировании () объединяемой таблицы после разделения по OrderID и DeliveryID, а также включения условия WHERE, что Delivery.Cum_Quant> = Order.Cum_Quant. С самым внешним условием WHERE CUM_RANK = 1 мы фильтруем только первую запись для DeliveryID, которая удовлетворяет условию.
Это решение хорошо работает для небольшой части моего набора данных, но происходит сбой, как только я использую полный набор данных из-за выделения памяти, так как многие полученные элементы соединяются с элементами заказа перед тем, как их фильтрует CUM_RANK из 1 Приблизительно с 5 миллионами запланированных дат поставки и 5 миллионами дат получения и до 100 поставок на OrderID объединенная таблица становится невероятно большой:
SELECT
*
,RANK() OVER(PARTITION BY Received.OrderID, Received.DeliveryID ORDER BY Received.CUM_QUANT) as CUM_RANK
FROM Orders
JOIN
(
SELECT
*
,RANK() OVER(PARTITION BY Received.OrderID ORDER BY ReceivedDate) AS Rank
,SUM(QUANTITY) OVER(PARTITION BY Received.OrderID ORDER BY ReceivedDate) AS Cum_Quant
FROM Received
)
ON Orders.OrderID = Delivery.OrderID
WHERE
Received.Cum_Quant >= Order.Cum_Quant
ORDER BY Orders.OrderID, Received.Cum_Quant
)
WHERE CUM_RANK = 1;
Мое сообщение об ошибке следующее:
SAP DBTech JDBC: [4]: не удается выделить достаточно памяти: проверьте трассировку для получения дополнительной информации
Есть идеи, как к этому подойти?
Доступ к проблеме основного стола
Мое другое предположение состояло в том, чтобы сделать сравнение Received.AccumQuant и Orders.AccumQuant в подзапросе SELECT оператора JOIN, чтобы мы избегали выполнения множества объединений. Но из оператора JOIN вы не можете получить доступ к таблице Orders:
SELECT *
FROM Orders
JOIN (
SELECT * FROM (
SELECT
*
,ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY ReceivedDate ASC) AS RowNumb
FROM Delivery
WHERE
WHERE Orders.OrderID = Received.OrderID
AND Received.AccumQuant >= Orders.AccumQuant --(this point doesnt worke since we cannot access the Orders table from here)
) AS DeliveryRanked
ON Orders.OrderID = Received.OrderID