我有一个人们评价项目的系统,我有两个表,我只想显示他们没有评价的用户项目。
item (i and simplified for this example)
----
item_id, name
1, widget1
2, widget2
我有一个评级表,它存储了三列
rating
------
item_id
user_id
rating
所以我想只返回该用户尚未评级的结果,现在我尝试了这个;
SELECT * FROM item LEFT JOIN rating r ON r.item_id = i.item_id WHERE r.user_id != USER_ID_OF_THE_USER;
然而,仍然返回了他们评价过的物品,正如其他人对物品进行了评价......
因此,如果我在数据库中有100个项目,用户a已经评级为30而用户b已经评级为70 ...那么用户a应该获得他们必须评分的70个项目,并且用户b应该获得他们没有的30个项目评价。
我的评级表有一个复合唯一键,所以如果他们将item_id = 1评级一次,然后再次评级,它只是更新评级值,它不会创建一个新行。为用户评分的每个项目插入一行。
这感觉应该很容易,而且可能是,但我被卡住了。
答案 0 :(得分:2)
我假设每个用户都必须为每个项目评分。如果是这样,那么您可以使用not exists
:
select *
from item i
where not exists (
select 1
from rating r
where i.item_id = r.item_id and r.user_id = ?)
假设您正在使用mysql
这一事实,left join / null
检查可能会更快:
select i.*
from item i
left join rating r on i.item_id = r.item_id and r.user_id = ?
where r.user_id is null
答案 1 :(得分:1)
只需使用反连接模式,如下所示:
SELECT i.*
FROM item i
LEFT
JOIN rating r
ON r.item_id = i.item_id
AND r.user_id = USER_ID_OF_THE_USER
WHERE r.user_id IS NULL
外部联接返回item中的所有行,以及用户的评级。如果rating
表中没有相关行,则rating
中的列的值将为NULL。所以我们需要的是添加一个WHERE
子句来过滤掉匹配的行。
答案 2 :(得分:0)
您可以使用此查询:
SELECT * FROM item i
WHERE NOT EXISTS (
SELECT * FROM rating r
WHERE r.item_id = i.item_id
AND r.user_id = USER_ID_OF_THE_USER);
这将返回那些没有用户USER_ID_OF_THE_USER评级的项目。