【问题标题】:find similar books based on purchased books based on book meta keywords根据书籍元关键字根据购买的书籍查找类似书籍
【发布时间】:2020-09-24 19:51:26
【问题描述】:

正如标题所暗示的,我想根据元关键字根据客户购买的书籍找到类似的书籍。下面的查询有效,但有人告诉我这可以简化。

SELECT DISTINCT oth.book 
FROM book_meta_keywords oth
     INNER JOIN books b ON b.id = oth.book
     , (SELECT bmk.meta_keyword AS metaKeyword, bmk.book AS book 
        FROM books b
        INNER JOIN customers_books cvb ON cvb.book = b.id
        INNER JOIN book_meta_keywords bmk ON bmk.book = b.id
        WHERE cvb.customer = 1 ) AS allCustomerPurchasedBooksMeta 
WHERE oth.meta_keyword = allCustomerPurchasedBooksMeta.metaKeyword 
     AND oth.book != allCustomerPurchasedBooksMeta.book 
     AND b.status = 'GOOD'

表结构

book_meta_keywords
book       meta_keyword
1            history
1            culture
2            culture
3            facts

books
id    status
1      GOOD
1      GOOD 
2       GOOD
3       GOOD

customers_books
book       customer
1            90


我应该得到输出书 - 2。

希望我的表格数据对你有用,如果不让我知道很高兴更正它。

更新

我现在使用下面的查询

SELECT bmk2.book
            FROM customers_books cb
            INNER JOIN book_meta_keywords bmk1 
                ON  bmk1.book = cb.book
            INNER JOIN book_meta_keywords bmk2 
                ON bmk2.meta_keyword = bmk1.meta_keyword
                AND bmk2.book <> bmk1.book
            INNER JOIN books b ON b.id = bmk2.book
            
            WHERE cb.customer = 1 AND b.status = 'PUBLISHED'

            GROUP BY bmk2.book
            ORDER BY MAX(b.modified_date) DESC      

这个查询返回

13
3
11

但我预计只有 3 本书,因为客户已经购买了第 13 和第 11 本书。 要查看客户购买的书籍,您可以运行以下返回 13、11 的查询

SELECT c.book FROM customers_books c WHERE c.customer = 1

下面的 DB fiddle 提供了完整的表结构和 SQL。 https://www.db-fiddle.com/f/tovUePp2WVffXLcuaxmJ8K/5

你认为是什么问题。我认为 这条线AND bmk2.book &lt;&gt; bmk1.book 不工作。

【问题讨论】:

  • 今日提示:随处切换到现代、明确的JOIN 语法!更容易编写(没有错误),更容易阅读和维护,如果需要更容易转换为外连接!
  • 您的问题是什么?您的编辑不清楚。但是--请不要插入编辑/更新,只是让您的帖子成为编辑时最好的演示文稿。请将您需要的内容放在您的帖子中,而不仅仅是在链接中。这包括minimal reproducible example--cut & paste & runnable 代码的代码部分,包括作为代码输入的最小代表性示例;期望和实际输出。 PS 逗号的优先级低于关键字连接,因此混合使用它们会造成混淆。 PS 工作代码问题属于Code Review。 PS你在研究简化的答案时学到了什么? How to Askhelp centerMeta Stack OverflowMeta Stack Exchange
  • @philipxy 现在可以了吗?

标签: sql postgresql join inner-join


【解决方案1】:

您可以通过连接来做到这一点:

select bmk2.book
from customer_books cb
inner join book_meta_keyword bmk1 
    on  bmk1.book = cb.book
inner join book_meta_keyword bmk2 
    on  bmk2.meta_keyword = bmk1.meta_keyword
    and bmk2.book <> bmk1.book
where cb.customer = 1

查询从客户1购买的书籍开始,然后带上对应的关键词,最后得到所有其他有任何共同关键词的书籍。

注意事项:

  • 如果书籍中有多个匹配的关键字,那么您将在结果集中得到重复。在这种情况下使用select distinct

  • 您不需要 table book 来获得您想要的结果 - 如果出于某种原因需要,您可以再加入一次加入

【讨论】:

  • 如果我想带好状态的书怎么办?
  • @Eric:这是from 子句末尾的另一个连接,用于引入表book(使用列bmk2.book),然后过滤where 中的status 原因...
  • 你的传奇。它现在完美无缺。非常简化的代码。
  • 如果我想按 book.created_date DESC 添加订单,我该如何添加?我收到错误:对于 SELECT DISTINCT,ORDER BY 表达式必须出现在选择列表第 19 行:WHERE cb.customer = 1 ORDER BY b.created_date DESC
  • @Eric:所以将该列添加到select 子句中...
猜你喜欢
  • 2021-04-30
  • 1970-01-01
  • 2020-05-12
  • 2012-09-12
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 2014-04-04
相关资源
最近更新 更多