You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Inner Join/Join On不符合预期,购书推荐SQL查询问题求助

解决基于元关键字的图书推荐SQL问题

我来帮你搞定这个图书推荐的SQL难题!先理清楚你的核心需求:你想给已购买书籍13和14(不过你提到查询SELECT c.book FROM customers_books c WHERE c.customer = 1返回13、11,这里可能是笔误?先按你最终要推荐书籍3的目标来)的客户,找出唯一和这两本书都共享元关键字的图书。

你提到的AND bmk2.book <> bmk1.book没按预期工作,问题出在这个条件只能排除当前关联的两本书相同,但没法排除客户已经购买的其他书籍,也没法确保推荐的图书和所有已购书籍都有匹配的关键字。

正确的SQL实现方案

我给你写一个逻辑清晰的查询,完美匹配你的需求:

-- 第一步:先获取客户已购买的书籍列表,用CTE让逻辑更清晰
WITH customer_purchased AS (
    SELECT book FROM customers_books WHERE customer = 1
)
-- 第二步:关联元关键字表,找到所有和已购书籍共享关键字的非已购图书
SELECT bmk2.book AS recommended_book
FROM book_meta_keywords bmk1
-- 关联已购书籍的关键字记录
JOIN customer_purchased cp ON bmk1.book = cp.book
-- 关联有相同关键字的其他图书记录
JOIN book_meta_keywords bmk2 ON bmk1.meta_keyword = bmk2.meta_keyword
-- 排除客户已经买过的书籍
WHERE bmk2.book NOT IN (SELECT book FROM customer_purchased)
-- 确保推荐的图书和所有已购书籍都有匹配的关键字(这一步是筛选核心)
GROUP BY bmk2.book
HAVING COUNT(DISTINCT bmk1.book) = (SELECT COUNT(*) FROM customer_purchased);

关键逻辑拆解

  1. CTEcustomer_purchased:把客户已购书籍单独提取出来,后续多次调用时更简洁,也方便后续调整查询条件。
  2. 双重关联元关键字表:bmk1对应已购书籍的关键字记录,bmk2对应有相同关键字的其他图书记录,这样能快速定位所有相关候选图书。
  3. NOT IN排除已购书籍:这比你原来的bmk2.book <> bmk1.book靠谱得多——后者只能排除bmk1对应的那一本,但如果bmk2是客户已购的另一本书(比如11),这个条件就拦不住,而NOT IN直接排除所有已购书籍。
  4. GROUP BY+HAVING确保全匹配:COUNT(DISTINCT bmk1.book)统计候选图书匹配的已购书籍数量,和已购书籍总数相等,就说明它和每一本已购书都有共享关键字,正好筛选出你要的书籍3(如果只需要和至少一本已购书匹配,去掉这两行即可)。

内容的提问来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:21:03