我在Oracle上,我需要在一個請求中同時使用ORDER BY
和ROWNUM
。我需要雙重嵌入我的內部查詢,因爲我想申請ORDER BY
第一個並選擇ROWNUM=1
然後。使用ORDER BY和ROWNUM的雙重嵌套查詢中的標識符無效
我的數據最多可以經由O.ID
進行過濾。但是,我在我的內部查詢中遇到錯誤,因爲O.ID
在那裏是未知標識。
我想要什麼:
SELECT
O.INSERTDATE OrderCreateDate,
-- Determine delivery date
(SELECT INSERTDATE FROM (
SELECT OP2.FK_ORDER, DD.ID, DD.INSERTDATE 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 gives me "Invalid identifier O.ID"
DD.DELFLAG IS NULL AND OP2.DELFLAG IS NULL
ORDER BY DD.CLOSED ASC, ABS(TRUNC(CURRENT_DATE-TO_DATE(TO_CHAR(DD.INSERTDATE, 'DDMMYYYY'), 'DDMMYYYY'))) ASC
) WHERE ROWNUM=1) DeliveryDate
FROM MY_ORDER_TABLE O
WHERE O.ID = 620; -- ID goes here!
我得到這個工作的唯一辦法,就是當我在中間SELECT
查詢WHERE
子句中進行篩選。但是這當然很慢,因爲內部SQL返回整個數據而沒有過濾。
SELECT
O.INSERTDATE OrderCreateDate,
-- Determine delivery date
(SELECT INSERTDATE FROM (
SELECT OP2.FK_ORDER, DD.ID, DD.INSERTDATE 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 DD.DELFLAG IS NULL AND OP2.DELFLAG IS NULL
ORDER BY DD.CLOSED ASC, ABS(TRUNC(CURRENT_DATE-TO_DATE(TO_CHAR(DD.INSERTDATE, 'DDMMYYYY'), 'DDMMYYYY'))) ASC
) WHERE ROWNUM=1 AND FK_ORDER=O.ID) DeliveryDate -- Filtering here
FROM MY_ORDER_TABLE O
WHERE O.ID = 620;
如何傳遞O.ID
到內部查詢或這怎麼能查詢被重新設計,仍保持ORDER BY
和ROWNUM
工作。
我的最終解決方案由金伯格漢森的建議,並通過輪輞改進:
(我不得不使用MIN()
代替MAX()
,雖然)
SELECT
O.INSERTDATE OrderCreateDate,
-- Determine delivery date
(SELECT MIN(DD.INSERTDATE) KEEP (DENSE_RANK FIRST ORDER BY
DD.CLOSED ASC, ABS(TRUNC(CURRENT_DATE-TRUNC(DD.INSERTDATE))) 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
DD.DELFLAG IS NULL AND OP2.DELFLAG IS NULL
) DeliveryDate
FROM MY_ORDER_TABLE O
WHERE O.ID = 620; -- ID goes here!
這些是大型查詢。相關部分並不完全突出。查看是否可以過濾出無關緊要的內容併發布可重現此問題的簡單示例 – Andomar 2014-09-02 06:14:25
與問題無關,但可以通過使用[TRUNC(date)](http://docs.oracle.com/)來簡化/改進查詢cd/B28359_01/server.111/b28286/functions209.htm)從日期時間中刪除時間部分。更改:'TO_DATE(TO_CHAR(DD.INSERTDATE,'DDMMYYYY','DDMMYYYY')''TRUNC(DD.INSERTDATE)' – Rimas 2014-09-02 07:34:35
@rims:謝謝你指出。 – user1438038 2014-09-02 20:45:11