MySQL加入查询 - 多次将表连接到自身

时间:2012-06-10 10:06:44

标签: mysql

我需要执行4次查询才能根据用户已表示感兴趣的项目向用户推荐项目:

选择用户已经喜欢的5个随机项目

SELECT item_id
FROM user_items
WHERE user_id = :user_person
ORDER BY RAND()
LIMIT 5

选择50个喜欢相同项目的人

SELECT user_id 
FROM user_items
WHERE user_id != :user_person
AND item_id = :selected_item_list
LIMIT 50

选择原始用户喜欢的所有项目

SELECT item_id
FROM user_items
WHERE user_id = :user_person

选择用户不想向用户建议的5个项目

SELECT item_id
FROM user_items
WHERE user_id = :user_id_list
AND item_id != :item_id_list
LIMIT 5

我想知道的是,我如何将其作为一个查询来解决?

我想要这样做的原因有几个:

  1. 目前,我必须先对“选择50个人”的查询进行5次检查并从中选出前50名
  2. 然后我必须优先'选择5项'查询50 *(初始用户喜欢的项目数)
  3. 一旦查询被删除,我打算将查询结果存储在cookie中(如果用户同意我使用cookie,否则他们根本没有得到'项目建议')密钥是查询的哈希值,意味着它每天只会触发一次/每周一次(这就是为什么我会返回5条建议并随机选择一个键来显示)

    基本上,如果有人知道如何将这些查询编写为一个查询,您能告诉我并解释查询中发生了什么吗?

1 个答案:

答案 0 :(得分:2)

这将选择您需要的所有项目:

SELECT DISTINCT ui_items.item_id
FROM user_items AS ui_own
JOIN user_items AS ui_others ON ui_own.item_id = ui_others.item_id
JOIN user_items AS ui_items ON ui_others.user_id = ui_items.user_id
WHERE ui_own.user_id = :user_person 
  AND ui_others.user_id <> :user_person
  AND ui_items.item_id <> ui_own.item_id

(请检查结果是否与您的版本完全相同 - 我在一个非常小的假数据集上进行了测试)

接下来,您只需缓存此列表并随机显示5个项目,因为ORDER BY RAND()非常低效(非确定性查询=&gt;无缓存)

编辑:添加DISTINCT以不显示重复的行。

您还可以通过删除DISTINCT并在查询末尾添加以下代码,按降序流行度顺序返回最受欢迎的建议:

GROUP BY ui_items.item_id
ORDER BY COUNT(*) DESC
LIMIT 20

在查询结束时返回20个最受欢迎的项目。