0

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

UserProfile,其中包含:

UserId  UserName
1           Adam

pages_Roles,其中包含:

RoleID RoleName
1      user
2      admin

pages_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 是否实际上运行两个选择并加入结果,也许是行号?

4

3 回答 3

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

执行 a 时,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
于 2013-03-31T15:18:19.563 回答
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”的行。

于 2013-03-31T15:17:50.997 回答
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 属性的关系,

希望这能澄清,干杯

于 2013-03-31T15:36:00.440 回答