我有这段代码:
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 ,但我不知道如何修改此代码以检查历史记录。 感谢您的帮助。
答案 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)
您不提供有关ORDER
和BOOKS
之间关系的信息。我假设:表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
;