我试图为每个客户找到他们没有购买的产品,以及哪些产品的评级最高 .
例如,在下表中,John购买了第1项和第2项,但未购买3,4或5.产品3和5没有评级,因此不包括在内,但产品4应包含在内,因为这是约翰没有买到的评价最高的项目 .
这是我的表结构和一些示例数据:
顾客
id | customer
----|---------
1 | john
2 | jenkins
3 | jane
4 | janet
产品
id | description
----|---------
1 | deoderant
2 | soap
3 | shampoo
4 | razor
5 | sponge
命令
customer_id | product_id
-------------|---------
1 | 1
1 | 2
2 | 3
2 | 4
3 | 5
率
customer_id | product_id | rate
-------------|------------|-------
1 | 1 | 3
2 | 2 | 2
2 | 4 | 3
4 | 2 | 4
2 回答
我开始编写一些子查询,然后将它们拼凑在一起 . 我个人的建议是在完成整个解决方案之前始终将问题分解成更小的位 .
例如,我需要知道的一件事是每个客户都没有购买的所有产品 . 我这样做是通过交叉加入客户和产品表(以获得所有配对)并删除已存在于订单表中的对,如下所示:
我还写了一个子查询来获得每个产品的平均评分 . 如果产品没有评级,则此查询将返回null:
现在,我可以将这两个作为子查询包含在内,并选择客户ID,产品ID以及他们尚未购买的每个产品的评级:
那是最难的部分 . 剩下要做的唯一事情是通过一些聚合来获得每个客户从他们尚未购买的商品中获得的最大评级,然后在最大评级与平均评级匹配的条件下将该聚合查询与上述查询相结合 . 所以,这是我放在一起的怪异查询:
这是MySQL工作台结果的快照:
需要注意的一点是,我没有消除关系 . 因此,例如,客户2没有购买产品1或2并且它们具有相同的评级,因此返回两行 .
我在MySQL中进行了测试,因为SQL Fiddle无法正常工作,但我得到了它的工作,所以如果您愿意,这里有一个Fiddle示例 .
如果您想为一位客户执行此操作,只需使用
order by
和limit
:如果您希望同时为所有客户提供服务,那就有点复杂了 . 一种方法是使用
substring_index()
/group_concat()
技巧: