问题
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
What I want to get is
Testcase Result
TC-1 OK
TC-5 <empty>
TC-8 FAIL
What I get is
Testcase Result
TC-1 OK
TC-8 FAIL
Query:
SELECT Testcases.Testcase, Tests.Result
FROM Testcases LEFT JOIN Tests ON Testcases.ID=Tests.TestCaseID
WHERE Tests.Release="1.1.111";
回答1:
There are two (subtly) different ways to do that:
SELECT Testcases.Testcase
, Tests.Result
FROM Testcases
LEFT JOIN Tests
ON ( ( Testcases.ID = Tests.TestCaseID )
AND ( Tests.Release = "1.1.111" )
)
and:
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
Insert one more row into table Testcases
, with ID=4, Testcase=20
and a row into table Tests
, with TestCaseID=4 Result="Whatever" Release="2.2.37"
to see the difference between the 2 options.
In short, first query will show all Testscases, with results shown only for tests having Release="1.1.111"
, the rest testcases will show Results as empty (NULL).
The second will show only Testscases having tests with Release="1.1.111"
. And also all Testcase without any test.
Note: The 1st query cannot be shown in Access' "Design" mode. You can save it in SQL mode but it appears that if you close and reopen it, Access erases some parentheses for unknown reasons. You can still run it though.
It (1st query) can also be written as:
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 )
or
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" )
)
or even better (because it can be shown in Design mode):
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)
回答2:
Put the filter into your join criteria, so that it's applied as part of the join, rather than filtered afterwards. e.g.:
SELECT Testcases.Testcase, Tests.Result
FROM (Testcases LEFT JOIN Tests ON ((Testcases.ID=Tests.TestCaseID)
AND (Tests.Release="1.1.111")))
来源:https://stackoverflow.com/questions/5693955/left-join-in-not-returning-full-rows-from-left-table-in-ms-access