Trong truy vấn con vô hướng mà bạn đang sử dụng, bạn chỉ có thể tham chiếu các bảng từ truy vấn "chính" "từ một cấp lồng nhau trở xuống", không phải bất kỳ xuống dưới nào nữa, như bạn đã thấy. (Tôi tin rằng hạn chế này đã được dỡ bỏ trong phiên bản 12, vì vậy bạn có thể chỉ cần nâng cấp cơ sở dữ liệu của mình?;-)
Trong truy vấn con vô hướng, bạn đang cố gắng lấy giá trị của cột INSERTDATE của hàng đầu tiên theo thứ tự của bạn. Điều đó cũng có thể được viết mà không cần lồng nhau như sau:
SELECT
O.INSERTDATE OrderCreateDate,
-- Determine delivery date
(SELECT MAX(DD.INSERTDATE) KEEP (
DENSE_RANK FIRST ORDER BY
DD.CLOSED ASC, ABS(TRUNC(CURRENT_DATE-TO_DATE(TO_CHAR(DD.INSERTDATE, 'DDMMYYYY'), 'DDMMYYYY'))) ASC
)
FROM MY_DELIVERYDATE_TABLE DD
JOIN MY_ORDERPOS_TABLE OP2 ON DD.FK_ORDERPOS=OP2.ID
LEFT OUTER JOIN MY_ORDER_TABLE O2 ON OP2.FK_ORDER=O2.ID
WHERE OP2.FK_ORDER=O.ID AND -- This will no longer give "Invalid identifier O.ID"
DD.DELFLAG IS NULL AND OP2.DELFLAG IS NULL
) DeliveryDate
FROM MY_ORDER_TABLE O
WHERE O.ID = 620; -- ID goes here!
KEEP (DENSE_RANK FIRST cho hàm MAX biết rằng nó sẽ tính toán MAX chỉ trong số các hàng xếp hạng đầu tiên trong mệnh đề ORDER BY. Vì vậy, nếu ORDER BY của bạn là "duy nhất", MAX sẽ chỉ được áp dụng cho một hàng ngang. Nếu ORDER BY của bạn không phải là "duy nhất" và có thể có các bản sao, bạn có thể nghĩ xem bạn muốn MAX hay MIN (hoặc thêm thứ gì đó vào ORDER BY để làm cho nó trở nên độc nhất.)
(Nếu bạn đang sử dụng phiên bản Oracle 12, một giải pháp thay thế cho KEEP (thủ thuật DENSE_RANK sẽ là sử dụng mệnh đề CHỈ 1 ROW ĐẦU TIÊN của câu lệnh SELECT.)