内部加入Access Query无法正常工作

时间:2014-10-17 09:56:02

标签: sql ms-access inner-join

这是数据库表

GroupsUsers

GroupID   -  UserID
--------------------
00001     - user1
00002     - user1
00003     - user2

GroupID   -  GroupName   -  Locked   - Deleted
---------------------------------------------
00001     - gruop1       -  True     - False
00002     - gruop2       -  False       - False
00003     - gruop3       -  False       - False    

我从GroupUsers表中获取下面给出的查询中的特定组的UserIds,但是我还想检查组表中的where子句中的组ID是locked=true还是delete=true然后它应该不在结果集中选择。

这是我尝试过的

SELECT DISTINCT GU.UserId From 
GroupsUsers AS GU
 INNER JOIN Groups AS G
 ON GU.GroupID = G.GroupId
WHERE  (((G.GroupId)=00001)) AND (((G.Locked)=False)) OR (((G.Deleted)=False));

但是此查询会返回给我所有用户

我只想获取特定群组的用户,如果其未被锁定或删除

4 个答案:

答案 0 :(得分:1)

您的查询未返回结果,因为您排除了WHERE子句中的其余记录。

查看您的数据:对GroupId ='0001'进行过滤只能为我们提供两个表之间的第一条记录。没有WHERE子句的结果集看起来像

  UserId  GroupId                            Locked  Delete
 ----------------     {Extended Result}    ----------------
  user1    0001                               Yes      No

让我们在那里添加WHERE子句:

If a GroupId has "yes" for either Locked or Delete, don't select it"

那就是你选择的唯一一行。

如果您取出GroupId条款中的WHERE,您会找到您(我认为?)寻找的结果。

userId
-------
user1   <- This is the second user1 in the GroupsUser's table
user2

这会产生结果:

SELECT DISTINCT GroupsUsers.userID,
FROM GroupsUsers
 INNER JOIN Groups ON GroupsUsers .ID = Groups.ID
WHERE (((Groups.Locked)=No)) OR (((Groups.Delete)=No));

如果您想检查特定的GroupId,并且您正在使用查询:

SELECT DISTINCT GU.UserId 
From GroupsUsers AS GU 
INNER JOIN Groups AS G 
ON GU.GroupID = G.GroupId 
WHERE (((G.Locked)=False)) 
    OR (((G.Deleted)=False)) AND (((G.GroupId)=00001));

您只是根据所需条件的75%过滤结果。您的查询为您提供UserId,其中Locked为false或GroupId = 00001时已删除为false。您需要将GroupId条件应用于WHERE子句的两个方面。

WHERE (G.Locked = False AND G.GroupId = 0001) OR (G.Deleted = False AND G.GroupId = 00001)

答案 1 :(得分:1)

您拥有的查询是:

SELECT DISTINCT GU.UserId 
From GroupsUsers AS GU INNER JOIN Groups AS G ON GU.GroupID = G.GroupId
WHERE  (((G.GroupId)=00001)) AND (((G.Locked)=False)) OR (((G.Deleted)=False));

这说的是:“从GroupsUsers中选择UserID,其中组ID为00001,而EITHER Locked或Deleted为false。

但是在您的问题中,您已经说过“检查where子句中的组ID是否已锁定= true或者在Groups表中是delete = true,那么不应在结果集中选择它。”

因此,如果lock = true,或者如果删除为true,则不选择它,那么当您在查询中测试相反状态时(即测试为false),您需要使用AND而不是OR:< / p>

SELECT DISTINCT GU.UserId 
From GroupsUsers AS GU INNER JOIN Groups AS G ON GU.GroupID = G.GroupId
WHERE  (((G.GroupId)=00001)) AND (((G.Locked)=False)) AND (((G.Deleted)=False));

PS:Access的查询生成器将大量括号放入where子句中,但在大多数情况下,它们并不是必需的,如果您删除它们,查询将更容易阅读和理解。此外,如果您需要编写查询以与多种类型的后端数据库进行交互,那么测试0而不是false将是有用的:

SELECT DISTINCT GU.UserId 
From GroupsUsers AS GU INNER JOIN Groups AS G ON GU.GroupID = G.GroupId
WHERE G.GroupId = 00001 AND G.Locked = 0 AND G.Deleted = 0

答案 2 :(得分:0)

尝试添加

and Locked='no' and Delete='no'
在您的查询结尾处

SELECT DISTINCT GU.UserId From 
GroupsUsers AS GU
 INNER JOIN Groups AS G
 ON GU.GroupID = G.GroupId
 WHERE GroupId='00001' and Locked='no' and Delete='no'

答案 3 :(得分:0)

如果您不希望在Locked状态为true时返回特定组,并且在Deleted状态为true时您不想返回它,则表示您希望在返回时返回两个值均为False

SELECT DISTINCT
  GU.UserId
FROM
  GroupsUsers AS GU
INNER JOIN
  Groups AS G ON GU.GroupID = G.GroupId
WHERE G.GroupId=00001
  AND G.Locked=False
  AND G.Deleted=False
;