内部联接的子查询并不存在(?)

时间:2016-10-26 14:49:20

标签: sql oracle

我有这段代码:

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 。我想检查用户之前是否借过这本书,因为我不想向他推荐他读过一次的书。 我有一个名为ORDERS的表,其中包含订单和attrubutes的历史记录: ID_ORDER ID_READER SIGNATURE 以及表 SIGNATURES 我有 SIGNATURE ID_BOOK 。当我调用此方法时,我使用 ID_READER ,但我不知道如何修改此代码以检查历史记录。 感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可以在WHERE子句中使用not exists:

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 用于选择用户。

编辑: 有关EXISTS / NOT EXISTS和IN / NOT IN的有趣讨论,请参阅以下链接:

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

答案 1 :(得分: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
    ;