共有3个表格:
Users table
------------
|uid|username|
------------
Values table
------------------
|vid|values|checked|
------------------
Relations
-----------
|cid|uid|vid|
-----------
“关系”表包含与值ids相关的用户ID。如何从值表中选择与关系表中给定用户ID无关的值id?
修改
到目前为止我尝试了什么:
SELECT vid FROM relations where uid=user_id //this gives me array of value ids
SELECT vid FROM values where vid!=vid1 AND vid!=vid2 .....
EDIT2: 可以找到基本解决方案here。但是有更有效的方法吗?如果表格对于值表和关系表都非常大,则基本解决方案效率不高。
答案 0 :(得分:1)
您使用的是哪个dbms?它是否支持减号条款?如果是,你可以做这样的事情
select vid from values
minus
select vid from relations where uid = @user_id
这应该给出未映射到给定用户ID的视频
另一种方法是通过not-exists子句(如果dbms不支持minus子句,则很方便)
select v.vid from values v where not exists (select 1 from relations r where
r.vid = v.vid and r.user_id = @user_id)
我会警告不要使用not in子句。它的性能是有问题的,如果内部查询返回一个空值,则会失败,虽然在你的情况下是不可能的,但是你应该养成一个习惯,永远不要在子查询中使用'not in'子句。只有当你有一个文字值列表时才使用它,例如'... vid不在(1,2,3,4)'。每当你必须根据另一个表中的值从一个表中“减去”某些内容时,使用“不存在”并且永远不会“不存在”
答案 1 :(得分:0)
你可以吗?
select vid from values where vid not in (select vid from relations where uid = user_id)
答案 2 :(得分:0)
我认为像这个查询这样的简单就足够了。
如果值表中的特定条目没有uid,则关系表中也不应该有条目。
SELECT vid
FROM values
LEFT JOIN relations on values.vid = relations.vid
WHERE relations.uid IS NULL
答案 3 :(得分:0)
select distinct v.vid
from values v
left join relations r on (r.vid=v.vid)
where r.uid != user_id
遗憾的是,MySQL不支持with
;不幸的是,这不会很好。
答案 4 :(得分:0)
如果您的“关系”表中的值恰好是0或1次,则可以使用JOIN
:
SELECT `Values`.`vid` FROM `Values`
LEFT JOIN `Relations` ON (`Values`.`vid` = `Relations`.`vid`)
WHERE `Relations`.`uid` != 1;
如果Value在Relations表中的次数超过1次,则无法使用,因为在这种情况下WHERE
会匹配另一行与其他uid不同的行。与NOT IN
相同,这也可以匹配具有相同视频的另一行但是另一个uid。
如果在Relation表中每个Value至少有一次,那么最有效的方法是只查询Relations表:
SELECT DISTINCT `Relations`.`vid` FROM `Relations`
WHERE `Relations`.`uid` != 1;
如果在“关系”表中值可以是0,1或更多次,最好的方法是使用EXISTS
(另请参阅taimur的答案):
SELECT `Values`.`vid` FROM `Values`
WHERE NOT EXISTS (
SELECT * FROM `Relations`
WHERE `Relations`.`vid` = `Values`.`vid` AND `Relations`.`uid` = 1
);
但是,EXISTS
比IN
或JOIN
慢一点,因此您应该比较执行时间的情况。
答案 5 :(得分:0)
我认为您可以执行这样的简单查询(假设用户标识符的数据类型为int
):
DECLARE @givenUserID int --local variable where you store the given user identifier
SELECT vid
FROM Values
WHERE vid NOT IN (SELECT vid FROM Relations where uid = @givenUserID)