什么联接是由“和”引起的?

时间:2013-03-31 15:12:20

标签: sql localdb

我有一个包含以下表格的localDB数据库:

UserProfile,其中包含:

UserId  UserName
1           Adam

webpages_Roles,其中包含:

RoleID RoleName
1      user
2      admin

webpages_UsersInRoles,它有两列(UserId,RoleId),并且是空白的。

我想要一个查询,按名称将用户按名称添加到角色中。 找出要插入的内容,如果我运行:

SELECT UserId, RoleID 
FROM UserProfile, webpages_Roles 
WHERE UserProfile.UserName = 'Adam' 
   OR webpages_roles.RoleName = 'admin';

我明白了:

UserId  RoleId
1       2
1       1

这是有道理的;这是一个交叉连接。但我基本上只想一次运行两个单独的选择并将它们粘在一起。我试过这个:

SELECT UserId, RoleID 
FROM UserProfile, webpages_Roles 
WHERE UserProfile.UserName = 'Adam' 
  AND webpages_roles.RoleName = 'admin';

它有效;我得到了UserId 1和RoleId 2.但我不明白“和”;是不是喜欢比较苹果和橘子?不应该是语法错误? localDB实际上是运行两个选择并加入结果,可能是行号吗?

3 个答案:

答案 0 :(得分:4)

执行此查询时:

SELECT UserId, RoleID 
FROM UserProfile, webpages_Roles
WHERE UserProfile.UserName = 'Adam' AND webpages_roles.RoleName = 'admin';

你正在做cross join。您应该养成特定交叉联接的习惯,并使用cross join而不是,。无论如何,这相当于:

SELECT UserId, RoleID
FROM (select u.*
      from UserProfile u
      where u.UserName = 'Adam'
     ) cross join
     (select w.*
      from webpages_Roles w
      WHERE w.RoleName = 'admin'
     ) w

在执行cross join时,您正在创建笛卡尔积 - 第一个表中的每一行都与另一个表中的所有行匹配。然后,where子句是此结果集的过滤器。

如果要对齐数据,那就更难了。以下是使用SQL Server语法的一种方法:

SELECT UserId, RoleID
FROM (select u.*, row_number() over (order by (select NULL)) as seqnum
      from UserProfile u
      where u.UserName = 'Adam'
     ) u join
     (select w.*, row_number() over (order by (select NULL)) as seqnum
      from webpages_Roles w
      WHERE w.RoleName = 'admin'
     ) w
     on u.seqnum = w.seqnum

答案 1 :(得分:2)

无论何时从多个表中进行选择,实际上都是隐式连接表。

SELECT UserId, RoleID 
FROM UserProfile, webpages_Roles; 

上面的查询将返回类似于:

的内容
UserId  UserName  RoleID RoleName
1           Adam  1      user
1           Adam  2      admin

所以当你添加where子句时:

SELECT UserId, RoleID 
FROM UserProfile, webpages_Roles 
WHERE UserProfile.UserName = 'Adam' AND webpages_roles.RoleName = 'admin';

它只返回UserProfile.Username为'Adam'且webpages_roles.RoleName为'admin'的行。

答案 2 :(得分:1)

这是正确的,而不是任何类型的错误的原因如下。 当你做的时候

SELECT UserId, RoleID
FROM UserProfile, webpages_Roles 

没有WHERE子句,你在标准SQL中得到的是关系的笛卡尔积,即UserProfile x webpages_Roles

在你的情况下反过来是一个现实(如DiscoInfiltrator的回答所示),

UserId  UserName  RoleID RoleName
1           Adam  1      user
1           Adam  2      admin

这意味着查询WHERE UserProfile.UserName = 'Adam' AND webpages_roles.RoleName = 'admin';的这一部分作用于包含UserName和RoleName属性的关系,

希望这澄清,欢呼