СЛЕДУЕТ ПРИСОЕДИНЯТЬСЯ, чтобы не вернуть полные строки из левой таблицы в MS Access

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 ответа

Решение

Есть два (тонких) разных способа сделать это:

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" чтобы увидеть разницу между 2 вариантами.

Короче говоря, первый запрос покажет все тестовые случаи с результатами, показанными только для тестов, имеющих Release="1.1.111"остальные тестовые примеры покажут результаты пустыми (NULL).

Второй покажет только Testscases, имеющие тесты с Release="1.1.111", А также все Testcase без каких-либо испытаний.

Примечание: 1-й запрос не может быть отображен в режиме Access "Design". Вы можете сохранить его в режиме SQL, но похоже, что если вы закроете и снова откроете его, Access удалит некоторые скобки по неизвестным причинам. Вы все еще можете запустить его, хотя.

Это (1-й запрос) также можно записать как:

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)

Поместите фильтр в критерии объединения, чтобы он применялся как часть объединения, а не фильтровался впоследствии. например:

SELECT Testcases.Testcase, Tests.Result
FROM (Testcases LEFT JOIN Tests ON ((Testcases.ID=Tests.TestCaseID)
 AND (Tests.Release="1.1.111")))
Другие вопросы по тегам