繁体   English   中英

来自3个不同表的SQL查询

[英]SQL query from 3 different tables

有3个表:

 Users table
 ------------
|uid|username|
 ------------ 

    Values table
 ------------------
|vid|values|checked|
 ------------------

  Relations
 -----------
|cid|uid|vid|
 -----------

关系表包含与值ID相关的用户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:基本解决方案可以在这里找到。 但是,有没有更有效的方法? 如果值表和关系表的表都很大,则基本解决方案效率不高。

您正在使用哪个dbms? 它支持减号条款吗? 如果是的话,你可以做这样的事情

    select vid from values 
    minus
    select vid from relations where uid = @user_id

这应该给出未映射到给定用户ID的vid

另一种方法是通过不存在子句(如果您的dbms不支持减号子句,则很方便)

    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 not in(1、2、3、4)”。 每当您必须根据另一个表中的值从一个表中“减去”某物时,请使用“不存在”并且永远不要“不存在”

你可以吗?

select vid from values where vid not in (select vid from relations where uid = user_id)

我认为类似此查询的简单操作就足够了。

如果值表中没有特定条目的uid,则关系表中也不应存在任何条目。

SELECT vid
FROM values
LEFT JOIN relations on values.vid = relations.vid
WHERE relations.uid IS NULL
select distinct v.vid
from values v
left join relations r on (r.vid=v.vid)
where r.uid != user_id

这是不幸的是,MySQL不支持with ; 不幸的是,这将不能很好地执行。

如果“关系”表中的值恰好是0或1倍,则可以为此使用JOIN

SELECT `Values`.`vid` FROM `Values`
LEFT JOIN `Relations` ON (`Values`.`vid` = `Relations`.`vid`)
WHERE `Relations`.`uid` != 1;

如果“关系”表中的“值”大于1次,则此方法将不起作用,因为在这种情况下, WHERE将匹配具有不同uid的另一行。 NOT IN相同,这也可以将具有相同vid的另一个行与另一个uid匹配。

如果每个值在Relations表中至少一次,那么最有效的方法是仅查询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
);

但是, EXISTSINJOIN慢一点,因此您应该比较您的情况下执行时间。

我认为您可以执行这样的简单查询(假设用户标识符的数据类型为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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM