СЛЕДУЕТ ПРИСОЕДИНЯТЬСЯ, чтобы не вернуть полные строки из левой таблицы в MS Access? - PullRequest
2 голосов
/ 17 апреля 2011
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 ]

5 голосов
/ 17 апреля 2011

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

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".А также все тестовые примеры без какого-либо теста.

Примечание: 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)
3 голосов
/ 17 апреля 2011

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

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