2016-10-26 11 views
0

我有這樣的代碼(?):子查詢與內部聯接,不存在

SELECT b.id_book 
    INTO var_idbook 
    FROM ORDERS o 
    INNER JOIN SIGNATURES s 
    ON o.signature=s.signature 
    INNER JOIN BOOKS b ON s.id_book=b.id_book 
    WHERE ((b.genre=var_genre)) 
    GROUP BY b.id_book 
    ORDER BY COUNT(o.ID_ORDER) DESC 
    FETCH FIRST ROW ONLY; 

此代碼工作正常,它的目標是給一本書,是最流行的某些流派的id_book 。我想檢查一下用戶之前是否借過這本書,因爲我不想向他推薦他讀過的書。 我有一個表名爲訂單在那裏我有訂單和attrubutes的歷史:ID_ORDERID_READERSIGNATURE也表SIGNATURES在那裏我有SIGNATUREID_BOOK。當我調用這種方法時,我使用ID_READER但我不知道如何修改此代碼以檢查歷史記錄。 非常感謝您的幫助。

回答

1

您可以使用不存在的WHERE子句中:

SELECT b.id_book 
    INTO var_idbook 
    FROM ORDERS o 
INNER JOIN SIGNATURES s 
    ON o.signature=s.signature 
INNER JOIN BOOKS b 
    ON s.id_book=b.id_book 
WHERE b.genre=var_genre 
    AND NOT EXISTS (SELECT 1 
        FROM ORDERS o2 
        INNER JOIN SIGNATURES s2 
         ON o2.signature = s2.signature 
        WHERE o2.id_reader = var_reader 
         AND s2.id_book = s.id_book) 
GROUP BY b.id_book 
ORDER BY COUNT(o.ID_ORDER) DESC 
FETCH FIRST ROW ONLY; 

因爲我沒有正確的數據集,我不能測試,但這個想法是對的id_book到查找看看用戶是否訂購了它並將其過濾掉。子查詢通過id_book連接到外部查詢,參數var_reader用於選擇用戶。

編輯: 對於一個有趣的討論上存在/ NOT EXISTS和IN/NOT IN請參考以下鏈接:

https://asktom.oracle.com/pls/apex/f?p=100:11:0::NO::P11_QUESTION_ID:442029737684

+0

這是什麼意思:「SELECT 1」? – monterinio

+0

「SELECT 1」表示您實際上並不擔心返回任何列,您只是測試存在的條件(WHERE子句)。還有人寫「SELECT NULL」。 –

+0

我在回覆中添加了關於AskTom關於EXISTS/NOT EXISTS的討論的鏈接,這可能有助於澄清事情。 –

0

你不提供有關ORDERBOOKS之間關係的信息。我假設:有ORDER_BOOK_LINK與book_id和order_id

SELECT b.id_book 
    -- INTO var_idbook 
    FROM ORDERS o 
    INNER JOIN SIGNATURES s ON o.signature=s.signature 
    INNER JOIN BOOKS b ON s.id_book=b.id_book 
    WHERE b.genre=var_genre 
     AND NOT EXSITS (SELECT NULL 
         FROM ORDER_BOOK_LINK obl 
         WHERE obl.Order_id = o.D_ORDER 
         AND obl.book_id = b.id_book) 
    GROUP BY b.id_book 
    ORDER BY COUNT(o.ID_ORDER) DESC 
    --FETCH FIRST ROW ONLY 
    ;