LEFT JOIN不返回MS Access中左表的所有行?

时间:2011-04-17 14:03:15

标签: database ms-access ms-access-2007

Testcases table
---------------
ID Testcase
1  TC-1
2  TC-5
3  TC-8

Tests table
-----------
ID TestCaseID Result Release
1  1          OK     1.1.111
2  3          FAIL   1.1.111

我想要的是

Testcase Result
TC-1     OK
TC-5     <empty>
TC-8     FAIL

我得到的是

Testcase Result
TC-1     OK
TC-8     FAIL

查询:

SELECT Testcases.Testcase, Tests.Result
FROM Testcases LEFT JOIN Tests ON Testcases.ID=Tests.TestCaseID
WHERE Tests.Release="1.1.111";

2 个答案:

答案 0 :(得分:5)

有两种(巧妙地)不同的方法:

SELECT Testcases.Testcase
     , Tests.Result
FROM Testcases
  LEFT JOIN Tests
    ON (  ( Testcases.ID = Tests.TestCaseID )
      AND ( Tests.Release = "1.1.111" )
       )

SELECT Testcases.Testcase
     , Tests.Result
FROM Testcases
  LEFT JOIN Tests
    ON Testcases.ID = Tests.TestCaseID
WHERE Tests.Release = "1.1.111"
   OR Tests.TestCaseID IS NULL

使用Testcases

在表ID=4, Testcase=20中再插入一行

和表格Tests中的一行,TestCaseID=4 Result="Whatever" Release="2.2.37",以查看两个选项之间的差异。

简而言之,第一个查询将显示所有测试用例,仅显示具有Release="1.1.111"的测试的结果,其余测试用例将结果显示为空(NULL)。

第二个将仅显示具有Release="1.1.111"测试的测试用例。还有所有Testcase都没有经过任何测试。

注意:第一个查询无法在Access“”设计“模式下显示。您可以将其保存在SQL模式下,但看起来如果您关闭并重新打开它,Access会因为未知原因而删除一些括号。你仍然可以运行它。

它(第一个查询)也可以写成:

SELECT Testcases.Testcase
     , g.Result
FROM Testcases
 LEFT JOIN
   ( SELECT * 
     FROM Tests
     WHERE ( Tests.Release = "1.1.111" )
   )
   AS g
 ON ( Testcases.ID = g.TestCaseID )

SELECT Testcases.TestCase
     , Tests.Result
FROM Testcases
  INNER JOIN Tests
    ON ( Testcases.ID = Tests.TestCaseID )
WHERE ( Tests.Release = "1.1.111" ) 

UNION ALL 

SELECT Testcases.TestCase, NULL
FROM Testcases 
WHERE NOT EXISTS 
  ( SELECT 1
    FROM Tests
    WHERE ( Testcases.ID = Tests.TestCaseID )
      AND ( Tests.Release = "1.1.111" )
  )

甚至更好(因为它可以在设计模式下显示):

SELECT Testcases.Testcase
     , IIf((Tests.Release="1.1.111"), Tests.Result, Null)
       AS Result
FROM Testcases
  LEFT JOIN Tests
    ON Testcases.ID = Tests.TestCaseID
GROUP BY Testcases.Testcase
       , IIf((Tests.Release="1.1.111"), Tests.Result, Null)

答案 1 :(得分:3)

将过滤器放入您的连接条件中,以便将其作为连接的一部分应用,而不是在之后进行过滤。 e.g:

SELECT Testcases.Testcase, Tests.Result
FROM (Testcases LEFT JOIN Tests ON ((Testcases.ID=Tests.TestCaseID)
 AND (Tests.Release="1.1.111")))